WPF TextBox with Watermark
WPF has simply the most powerful templating and visual engine that is available at the moment for designing your UI. A requirement came up in a project that required a watermarked textbox for displaying some contextual help.
With WPF this becomes trivial. So lets first create a control that extends TextBox to add our watermark text property.
public class TextBoxWithHelp : TextBox
{
public string HelpText
{
get {return (string)GetValue(HelpTextProperty); }
set { SetValue(HelpTextProperty, value); }
}
public static readonly DependencyProperty HelpTextProperty =
DependencyProperty.Register("HelpText",
typeof(string),
typeof(TextBoxWithHelp),
new PropertyMetadata(String.Empty));
}
This code creates us a control that functions exactly the same as a TextBox but allows us a DependencyProperty we can bind some watermark to. So now can we use this control and style it as needed. And this becomes a pretty simple task. What we will do is take the default style of a TextBox and add an additional element and some additional triggers. For brevity, I’ve omitted all the TemplateBindings which are not required for this example.
<Style TargetType="{x:Type local:TextBoxWithHelp}">
<Setter
Property="Template">
<Setter.Value>
<ControlTemplate
TargetType="{x:Type local:TextBoxWithHelp}">
<Microsoft_Windows_Themes:ListBoxChrome
x:Name="Bd"
SnapsToDevicePixels="true" >
<Grid>
<ScrollViewer
x:Name="PART_ContentHost" />
<TextBlock
x:Name="PART_HelpTextElement"
Text="{TemplateBinding HelpText}"
Visibility="Collapsed"/>
</Grid>
</Microsoft_Windows_Themes:ListBoxChrome>
<ControlTemplate.Triggers>
<Trigger
Property="Text"
Value="">
<Setter
TargetName="PART_HelpTextElement"
Property="Visibility"
Value="Visible"/>
</Trigger>
<Trigger
Property="Text"
Value="{x:Null}">
<Setter
TargetName="PART_HelpTextElement"
Property="Visibility"
Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
What we have changed in the base TextBox style is the addition of the “PART_HelpTextElement” TextBlock. This is the element that the watermark will sit in and is collapsed by default. In the control template triggers collection, you’ll notice that the moment that the control’s Text Property is “” or null, the watermark TextBlock’s visibility property will be set to Visible and the watermark will become visible.
This is a simple solution for a problem that occurs quite frequently. Because of the power of WPF, you are able to style the watermark in any fashion you require.