Convertion of long in Windows store application - windows-store-apps

I am writing a windows 8 store application and have the following problem:
I have a textblock binded to a long property of an object.
The long value is 123456789, however, on the screen i only see the char 1.
How can i solve this, and why the convertion to string doesn't work like it should?

Try this and let me if it works for you or not.
XAML
<Page.DataContext>
<local:myVm />
</Page.DataContext>
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<GridView ItemsSource="{Binding col}">
<GridView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" Margin="20" FontSize="20" />
</DataTemplate>
</GridView.ItemTemplate>
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<WrapGrid MaximumRowsOrColumns="3" />
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>
</Grid>
myVm.cs
public class myVm : INotifyPropertyChanged
{
public myVm()
{
col.Add(long.MaxValue);
col.Add(long.MaxValue);
col.Add(long.MaxValue);
col.Add(long.MaxValue);
col.Add(long.MaxValue);
col.Add(long.MaxValue);
}
private ObservableCollection<long> _col = new ObservableCollection<long>();
public ObservableCollection<long> col
{
get { return _col; }
set
{
_col = value;
NotifyPropertyChanged("col");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this,
new PropertyChangedEventArgs(propertyName));
}
}
}

Related

How to add ListView to player from PlayerFramework (windows app)?

I added a button to player from PlayerFramework, when click that button, a ListView appear for select video quality.
But I dont know how to implement ItemClicked event to handle when user click a item in ListView. Anyone can help me?
My code:
Entertainment.xaml
<AppBarButton x:Name="QualityButton"
Grid.Column="3"
Width="30"
Height="30"
Margin="8,0,8,0"
Icon="Setting"
Style="{TemplateBinding TransportBarButtonStyle}"
Visibility="Visible">
<AppBarButton.Flyout>
<Flyout>
<ListView Name="listView"
IsItemClickEnabled="True"
ItemsSource="{Binding List}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Flyout>
</AppBarButton.Flyout>
</AppBarButton>
CustomInteractiveViewModel.cs
public class CustomInteractiveViewModel : InteractiveViewModel
{
public CustomInteractiveViewModel(List<string> list, MediaPlayer player)
: base(player)
{
List = list;
}
public List<string> List { get; set; }
}
MainPage.cs
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
var list = new List<string> { "360p", "480p", "720p" };
player.InteractiveViewModel = new CustomInteractiveViewModel(list, player);
player.Source = new Uri(Video, UriKind.RelativeOrAbsolute);
}
MainPage.xaml
<Page x:Class="testPlayer.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:testPlayer"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:mmppf="using:Microsoft.PlayerFramework"
xmlns:webvtt="using:Microsoft.PlayerFramework.WebVTT"
mc:Ignorable="d">
<Page.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Themes/Entertainment.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Page.Resources>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<mmppf:MediaPlayer Name="player" />
</Grid>
</Page>
It is not supported to binding event like ItemClick or SelectionChanged in ResourceDictionary, a simple method is to create the code behind of this ResourceDictionary, but to maintain the MVVM pattern integrity, it's better to register a Attached property, and bind events to this attached property.
You can change your code in Entertainment.xaml like this:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="using:Microsoft.PlayerFramework.Controls"
xmlns:local="using:Microsoft.PlayerFramework">
...
<AppBarButton x:Name="QualityButton" Grid.Column="3" Width="30" Height="30" Margin="8,0,8,0"
Icon="Setting" Style="{TemplateBinding TransportBarButtonStyle}" Visibility="Visible">
<AppBarButton.Flyout>
<Flyout>
<ListView Name="listView" IsItemClickEnabled="True" ItemsSource="{Binding List}" controls:CustomInteractiveViewModel.ItemClickCommand="{Binding ItemClickedCommand}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Flyout>
</AppBarButton.Flyout>
</AppBarButton>
...
</ResourceDictionary>
and the code in CustomInteractiveViewModel.cs:
public class CustomInteractiveViewModel : InteractiveViewModel
{
public CustomInteractiveViewModel(List<string> list, MediaPlayer player, DelegateCommand<string> itemclickedcommand)
: base(player)
{
List = list;
ItemClickedCommand = itemclickedcommand;
}
public List<string> List { get; set; }
public DelegateCommand<string> ItemClickedCommand { get; set; }
public static DependencyProperty ItemClickCommandProperty =
DependencyProperty.RegisterAttached("ItemClickCommand",
typeof(ICommand),
typeof(CustomInteractiveViewModel),
new PropertyMetadata(null, OnItemClickCommandChanged));
public static void SetItemClickCommand(DependencyObject target, ICommand value)
{
target.SetValue(ItemClickCommandProperty, value);
}
public static ICommand GetItemClickCommand(DependencyObject target)
{
return (ICommand)target.GetValue(ItemClickCommandProperty);
}
private static void OnItemClickCommandChanged(DependencyObject target,
DependencyPropertyChangedEventArgs e)
{
var element = target as ListViewBase;
if (element != null)
{
if ((e.NewValue != null) && (e.OldValue == null))
{
element.ItemClick += OnItemClick;
}
else if ((e.NewValue == null) && (e.OldValue != null))
{
element.ItemClick -= OnItemClick;
}
}
}
private static void OnItemClick(object sender, ItemClickEventArgs e)
{
GetItemClickCommand(sender as ListViewBase).Execute(e.ClickedItem);
}
}
Finally in your MainPage.cs:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
var list = new List<string> { "360p", "480p", "720p" };
var ItemClickedCommand = new DelegateCommand<string>(ItemClicked);
player.InteractiveViewModel = new CustomInteractiveViewModel(list, player, ItemClickedCommand);
}
public void ItemClicked(string item)
{
//TODO:
}
And the DelegateCommand<T> class is like this:
public class DelegateCommand<T> : ICommand
{
private readonly Action<T> _execute;
private readonly Func<T, bool> _canExecute;
public event EventHandler CanExecuteChanged;
public DelegateCommand(Action<T> execute, Func<T, bool> canexecute = null)
{
if (execute == null)
throw new ArgumentNullException(nameof(execute));
_execute = execute;
_canExecute = canexecute ?? (e => true);
}
public bool CanExecute(object p)
{
try { return _canExecute(ConvertParameterValue(p)); }
catch { return false; }
}
public void Execute(object p)
{
if (!this.CanExecute(p))
return;
_execute(ConvertParameterValue(p));
}
private static T ConvertParameterValue(object parameter)
{
parameter = parameter is T ? parameter : Convert.ChangeType(parameter, typeof(T));
return (T)parameter;
}
public void RaiseCanExecuteChanged()
{
CanExecuteChanged?.Invoke(this, EventArgs.Empty);
}
}

MVVMcross Command Binding fire Exception

I experience an issue when i try to use a command to open a Second View Model V4.0.Beta5.
I followed the Exemple described in N+1 Video series https://www.youtube.com/playlist?list=PLR6WI6W1JdeYSXLbm58jwAKYT7RQR31-W
First ViewModel
public class FirstViewModel
: MvxViewModel
{
private string _hello = "Hello MvvmCross";
public string Hello
{
get { return _hello; }
set
{
_hello = value;
RaisePropertyChanged(() => Hello);
}
}
private Cirrious.MvvmCross.ViewModels.MvxCommand _goSecondViewCommand;
public System.Windows.Input.ICommand GoSecondViewCommand
{
get
{
_goSecondViewCommand = _goSecondViewCommand ??
new Cirrious.MvvmCross.ViewModels.MvxCommand(DoGoSecondView);
return _goSecondViewCommand;
}
}
private void DoGoSecondView()
{
base.ShowViewModel<SecondViewModel>();
}
}
Second View model
public class SecondViewModel :MvxViewModel
{
private string _hello2 = "Hello2 MvvmCross";
public string Hello2
{
get { return _hello2; }
set
{
_hello2 = value;
RaisePropertyChanged(() => Hello2);
}
}
}
First View
<views:MvxWindowsPage
x:Class="TestCommand.UWP.Views.FirstView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TestCommand.UWP"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:views="using:Cirrious.MvvmCross.WindowsUWP.Views"
mc:Ignorable="d">
<Grid>
<TextBox x:Name="textBox" HorizontalAlignment="Left" Margin="70,92,0,0" TextWrapping="Wrap" Text="FirstView" VerticalAlignment="Top" Width="223"/>
<Button x:Name="button" Command="{Binding GoSecondViewCommand}" Content="Button" HorizontalAlignment="Left" Height="108" Margin="70,346,0,0" VerticalAlignment="Top" Width="223"/>
</Grid>
Second view
<views:MvxWindowsPage
x:Class="TestCommand.UWP.Views.SecondView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TestCommand.UWP.Views"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:views="using:Cirrious.MvvmCross.WindowsUWP.Views"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<Grid />
Setup Class:
public class Setup : MvxWindowsSetup
{
public Setup(Frame rootFrame) : base(rootFrame)
{
}
protected override IMvxApplication CreateApp()
{
return new TestCommand.Core.App();
}
}
If you want you can download the solution Here:
https://onedrive.live.com/redir?resid=A5D9789788DE33CB!36079&authkey=!AKs9nsG28iI6nQQ&ithint=file%2czip.
The possible reason is you don't use Setup correctly in your UWP app, here is what I do to make this work:
1) Create two ViewModels in the UWP app: FirstViewModel and SecondViewModel
2) Create a Setup class in Setup.cs file:
public class Setup : MvxWindowsSetup
{
public Setup(Frame rootFrame) : base(rootFrame)
{
}
protected override IMvxApplication CreateApp()
{
return new AppSetup();
}
}
public class AppSetup : MvxApplication
{
public override void Initialize()
{
RegisterAppStart<FirstViewModel>();
}
}
3) FirstView.xaml:
<StackPanel>
<TextBox x:Name="textBox" HorizontalAlignment="Left" Margin="70,92,0,0" TextWrapping="Wrap" Text="FirstView" VerticalAlignment="Top" Width="223"/>
<TextBlock Height="50" Text="{Binding Hello}" />
<Button x:Name="button" Command="{Binding GoSecondViewCommand}" Content="Button" HorizontalAlignment="Left" VerticalAlignment="Top" Width="223" Height="50" />
</StackPanel>
4) SecondView.xaml:
<StackPanel>
<TextBox x:Name="textBox" HorizontalAlignment="Left" Margin="70,92,0,0" TextWrapping="Wrap" Text="SecondView" VerticalAlignment="Top" Width="223"/>
<TextBlock Height="50" Text="{Binding Hello2}" />
</StackPanel>
5) In App.xaml.cs file, make the following changes in OnLaunched method:
protected override void OnLaunched(LaunchActivatedEventArgs e)
{
......
if (rootFrame.Content == null)
{
var setup = new Setup(rootFrame);
setup.Initialize();
var start = Mvx.Resolve<IMvxAppStart>();
start.Start();
}
// Ensure the current window is active
Window.Current.Activate();
}
By the way, the MvvmCross version is 3.5.1
Check the Completed sample on Github
Update for exception in OnNavigationFailed method:
Please comment this line in FirstView and SecondView's code behind:
ViewModel = new FirstViewModel();
ViewModel = new SecondViewModel();
The MvvmCross has set the ViewModel automatically.

Longlist will not update at load

I am having some problems making a long list selector load my data, and i have been unable to find a solution to this problem.
This is my xaml:
<phone:LongListSelector x:Name="animeList"
Margin="0,0,-12,0"
ItemsSource="{Binding Animes}"
Tap="AnimeList_OnTap">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17">
<TextBlock Text="{Binding Name}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}">
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu IsZoomEnabled="false">
<toolkit:MenuItem Header="Add as favorit" Click="AddFavorite" />
</toolkit:ContextMenu>
</toolkit:ContextMenuService.ContextMenu>
</TextBlock>
</StackPanel>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
My view model is simple:
public ObservableCollection<AnimeItemViewModel> _animes { get; set; }
public ObservableCollection<AnimeItemViewModel> Animes
{
get { return _animes; }
set
{
if (value != _animes)
{
_animes = value;
NotifyPropertyChanged("Animes");
}
}
}
And how i load my data:
public MainPage()
{
InitializeComponent();
DataContext = App.ViewModel;
this.Loaded += OnLoaded;
}
private void OnLoaded(object sender, RoutedEventArgs routedEventArgs)
{
ObservableCollection<AnimeItemViewModel> _animes = new ObservableCollection<AnimeItemViewModel>();
foreach (var i in App.AnimeList.List)
_animes.Add(new AnimeItemViewModel() { AId = i.AId, Name = i.Name });
App.ViewModel.Animes = _animes;
}
And lastly just to show that there are data in the list
Update: I also have a search function, and if i enter a search text will the longlist update, but i am for some reason unable to scroll
private void OnKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
ObservableCollection<AnimeItemViewModel> _animes = new ObservableCollection<AnimeItemViewModel>();
foreach (var i in App.AnimeList.List)
if (string.IsNullOrWhiteSpace(SearchTextBox.Text) || i.Name.ToLower().Contains(SearchTextBox.Text.ToLower()))
_animes.Add(new AnimeItemViewModel() { AId = i.AId, Name = i.Name });
App.ViewModel.Animes = _animes;
}
}
Try placing your loading code in OnNavigatedTo. As for the scrolling issue - setting a proper height to the StackPanel. Let me know if it works.

MainviewModel windows phone 8

This is the class where I'm trying to load the data
PAGE2 XAML
<xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DataContext="{d:DesignData SampleData/MainViewModelSampleData.xaml}"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
shell:SystemTray.IsVisible="True">
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel Grid.Row="0" Margin="12,17,0,28">
<TextBlock Text="MY APPLICATION" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock Text="page name" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Margin="0,10,0,0" Grid.Row="1">
<phone:LongListSelector x:Name="MainLongListSelector" Margin="10,2,0,0" ItemsSource="{Binding Items2}" SelectionChanged="MainLongListSelector_SelectionChanged">
<phone:LongListSelector.ItemTemplate>
<DataTemplate>
<StackPanel Margin="0,0,0,17" Height="154">
<TextBlock Text="{Binding LineOne}" TextWrapping="Wrap" Style="{StaticResource PhoneTextExtraLargeStyle}" FontSize="20" Margin="0,0,0,538" Height="150"/>
</StackPanel>
</DataTemplate>
</phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>
</Grid>
</Grid>
</phone:PhoneApplicationPage>
MainViewModel
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using Package_Tracker_P.Resources;
using System.Collections.Generic;
using Windows.Storage;
using System.IO;
using System.Threading.Tasks;
using System.Windows;
using System.Text.RegularExpressions;
namespace Package_Tracker_P.ViewModels
{
public class MainViewModel : INotifyPropertyChanged
{
public static List<Car> carlist = new List<Car>();
public MainViewModel()
{
this.Items = new ObservableCollection<ItemViewModel>();
this.Items2 = new ObservableCollection<ItemViewModel>();
}
/// <summary>
/// A collection for ItemViewModel objects.
/// </summary>
public ObservableCollection<ItemViewModel> Items { get; private set; }
public ObservableCollection<ItemViewModel> Items2 { get; private set; }
private string _sampleProperty = "Sample Runtime Property Value";
/// <summary>
/// Sample ViewModel property; this property is used in the view to display its value using a Binding
/// </summary>
/// <returns></returns>
public string SampleProperty
{
get
{
return _sampleProperty;
}
set
{
if (value != _sampleProperty)
{
_sampleProperty = value;
NotifyPropertyChanged("SampleProperty");
}
}
}
/// <summary>
/// Sample property that returns a localized string
/// </summary>
public string LocalizedSampleProperty
{
get
{
return AppResources.SampleProperty;
}
}
public bool IsDataLoaded
{
get;
private set;
}
/// <summary>
/// Creates and adds a few ItemViewModel objects into the Items collection.
/// </summary>
public async void LoadData(Car toyota)
{
// Sample data; replace with real data
carlist.Add(toyota);
this.Items.Add(new ItemViewModel() { ID = (Items.Count.ToString()), LineOne = toyota.status, LineTwo = "", LineThree = "" });
this.IsDataLoaded = true;
//await openfile();
await IO.WriteToFile();
}
public async void LoadData()
{
try
{
stuff();
}
catch (Exception ex)
{
MessageBox.Show("Error Loading Data");
}
}
public void stuff()
{
this.Items2.Add(new ItemViewModel() { ID = (Items2.Count.ToString()), LineOne = "Auto Detect", LineTwo = "", LineThree = "" });
this.IsDataLoaded = true;
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}
The problem is is not loading the data for PAGE2. It is loading it for the main page using items1. While the app is loading it calls LoadData() and that call stuff() which is adding data to items2. It is correctly
binded in the xaml file for PAGE TWO in the textblock. Am I missing something?
i think the main problem with this code is that you have not set the datacontext of the page 2
like if you are using MVVM light then
DataContext = {Binding MainViewModel,Source="{StaticResource Locator}}"

Why there is no PlaceHolder like property in XAML TextBox

Is there any "placeholder type" property availble for textbox in xaml in windows phone 8
There is the PhoneTextBox in the official Windows Phone Toolkit, covered here.
Sample code:
<toolkit:PhoneTextBox Hint="Password"/>
To add toolkit to your project :
Type the following into your package manager console :
PM> Install-Package WPtoolkit
And
xmlns:toolkit="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone.Controls.Toolkit"
inside <phone:PhoneApplicationPage tag in the xaml page
Try like this below code:
<TextBox x:Name="InvoiceDate" Text="" Width="300" TextAlignment="Left" Height="30" Grid.Row="0" Grid.Column="3" Grid.ColumnSpan="2" />
<TextBlock IsHitTestVisible="False" Text="Men att läsa" Width="300" TextAlignment="Left" Height="30" Grid.Row="0" Grid.Column="3" Grid.ColumnSpan="2" Padding="5, 5, 5, 5" Foreground="LightGray">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding Text, ElementName=InvoiceDate}" Value="">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
There is no placeholder property for TextBox. I use the following solution to work around this for a username textbox:
XAML:
<Grid>
<TextBlock Name="UsernamePlaceholder" Text="Username" />
<TextBox Name="UsernameTextBox" Text="" GotFocus="TextBox_GotFocus" LostFocus="TextBox_LostFocus"/>
</Grid>
Code:
private void TextBox_GotFocus(object sender, RoutedEventArgs e)
{
UsernamePlaceholder.Visibility = Visibility.Collapsed;
}
private void TextBox_LostFocus(object sender, RoutedEventArgs e)
{
if (sender is TextBox)
{
var textbox = sender as TextBox;
if (string.IsNullOrEmpty(textbox.Text))
{
UsernamePlaceholder.Visibility = Visibility.Visible;
}
}
}
This basically replaces the TextBox with a Grid-element, containing a TextBox and a TextBlock (working as placeholder). Then when the textbox is focused, the textblock is hidden, and when it looses focus the textblock is shown if the textbox is empty.
My solution is based on the answer of PKENO
XAML (UserControl):
<UserControl x:Class="FestivalProject.Controls.TextBoxPH"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d">
<TextBox x:Name="testTextBox" Margin="0" LostFocus="testTextBox_LostFocus" GotFocus="testTextBox_GotFocus"/>
</UserControl>
Code behind UserControl:
public partial class TextBoxPH : UserControl
{
private String _Text;
public String Text
{
get { return _Text; }
set {
_Text = testTextBox.Text = value;
}
}
private String _PlaceHolder;
public String PlaceHolder
{
get { return _PlaceHolder; }
set {
_PlaceHolder =testTextBox.Text = value;
}
}
public TextBoxPH()
{
InitializeComponent();
}
private void testTextBox_LostFocus(object sender, RoutedEventArgs e)
{
if (string.IsNullOrEmpty(testTextBox.Text)) testTextBox.Text = PlaceHolder;
}
private void testTextBox_GotFocus(object sender, RoutedEventArgs e)
{
if (testTextBox.Text.Equals(PlaceHolder, StringComparison.OrdinalIgnoreCase)) testTextBox.Text = string.Empty;
}
}
XAML (in Window):
<txtPH:TextBoxPH Margin="5" Grid.ColumnSpan="2" PlaceHolder="PlaceholderText"/>
Probably not the most efficient way, but it works.