Watermark for TextBox in Windows 8 applications

  • Tutorial
Recently, it has become fashionable, in addition to an explanatory inscription for a TextBox, and also to write some help on the TextBox itself. It should all look like the picture to attract attention. While the user has not entered anything, a prompt is highlighted. If the user has entered text, the tooltip is not displayed. God knows what a complicated logic, but because the triggers were taken away from the ControlTemplate in the Windows Store applications, you will have to do this not with a style, but with a new control.
Under the cut, we will walk you through the development of such a component, focused on those who are first time approaching the development of their controls. For those who already program for the Windows Store, there will be no revelations, but if it's not difficult, post recommendations in the comments, maybe someone really decides to make a good control for such a task.

Go.
We create a new Windows Store application. Add a new assembly to Solution (right-click on the solution, in the context menu Add -> New Project):

Add a new element to this assembly (right-click on the project, Add -> New Item):

In the cs file of our control, change the ancestor to TextBox:
public sealed partial class WaterMarkedTextBox : TextBox

Also, we will have to change the markup by replacing the base component and deleting the contents:

These simple actions allowed us to get all the fields and methods that the base TextBox had in its component. The only thing that does not suit us is the lack of TextBox's ability to show a hint. We redefine the template of our descendant TextBox, adding a TextBlock to it to display a hint:

Because you cannot work with visual components in the constructor yet, we will subscribe to the component loading event and we will do all the useful work in the handler of this event:

public WaterMarkedTextBox()
{
    this.InitializeComponent();            
    Loaded += WaterMarkedTextBox_Loaded;
}

To determine if we have focus on the element or not, add a field:

private bool _isFocused;

Well, we need DependencyProperty to store the hint text:

/// 
/// Подсказка показываемая пользователю
/// 
public string WaterMark
{
    get { return (string)GetValue(WaterMarkProperty); }
    set { SetValue(WaterMarkProperty, value); }
}
/// 
/// Static part of dependency property WaterMark
/// 
public static readonly DependencyProperty WaterMarkProperty =
    DependencyProperty.Register("WaterMark", typeof(string), typeof(WaterMarkedTextBox), new PropertyMetadata(""));

That's it, write the processing of loading the component, getting the input focus and losing it:

void WaterMarkedTextBox_Loaded(object sender, RoutedEventArgs e)
{
    var grid = (Grid)VisualTreeHelper.GetChild(this, 0);
    TextBox innerTextBox = (TextBox)grid.Children[0];
    innerTextBox.GotFocus += WaterMarkedTextBox_GotFocus;
    innerTextBox.LostFocus += WaterMarkedTextBox_LostFocus;
    ChangeWatermarkTextVisibility();
}
void WaterMarkedTextBox_LostFocus(object sender, RoutedEventArgs e)
{
    _isFocused = false;
    ChangeWatermarkTextVisibility();
}
void WaterMarkedTextBox_GotFocus(object sender, RoutedEventArgs e)
{
    _isFocused = true;
    ChangeWatermarkTextVisibility();
}

Well, the most recent method to change the visibility of a hint:

private void ChangeWatermarkTextVisibility()
{
    var grid = (Grid)VisualTreeHelper.GetChild(this, 0);
    TextBlock watermarkText = (TextBlock)grid.Children[1];
    if (!string.IsNullOrEmpty(Text) || _isFocused)
    {
        watermarkText.Visibility = Visibility.Collapsed;
    }
    else
    {
        watermarkText.Visibility = Visibility.Visible;
    }
}

Putting the solution together.
Because I took the Blank App as the initial project, then I entered the following markup on the main form:

In order not to think about connecting namespace, I usually drag new components onto the form from the Tools panel:

Well, how it all looks can be seen in the first picture of this post, or by repeating my steps and launching the application.

Also popular now: