Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

XAML only WPF Watermarked TextBox

0.00/5 (No votes)
5 Mar 2015 2  
Adding a watermark to a WPF TextBox by only using XAML. No extensions. No Converters.

Introduction

A lot of the examples I found on how to add a watermark to a TextBox involve a significant amount of code-behind, handling text changed events, or making use of a custom IValueConverter or IMultiValueConverter. In this article, I'll show how to add a watermark to a TextBox by only using XAML markup.

Background

A demonstration project I recently worked on was pre-setting the text of a textbox as kind of a poor-man's watermark. But when you started typing in the box, you have to first clear away the default value. That's not a watermark, that's just annoying. I wanted to fix this, but I didn't want to write a bunch of C# code to make it happen. I knew it could be done in XAML.

Using the code

Let's just jump right to it

XML
<Grid x:Name="WatermarkWrapper">
    <TextBox x:Name="WaterMarkedTextBox" Text="{Binding Text, FallbackValue='Hello World'}" />
    <TextBlock IsHitTestVisible="False" Text="{Binding WatermarkText}" VerticalAlignment="Center" HorizontalAlignment="Left" Margin="10,0,0,0" Foreground="DarkGray">
        <TextBlock.Style>
            <Style TargetType="{x:Type TextBlock}">
                <Setter Property="Visibility" Value="Collapsed" />
                <Style.Triggers>
                    <MultiDataTrigger>
                        <MultiDataTrigger.Conditions>
                            <Condition Binding="{Binding Text}" Value="" />
                            <Condition Binding="{Binding ElementName=WaterMarkedTextBox, Path=IsKeyboardFocused}" Value="False" />
                        </MultiDataTrigger.Conditions>
                        <MultiDataTrigger.Setters>
                            <Setter Property="Visibility" Value="Visible" />
                        </MultiDataTrigger.Setters>
                    </MultiDataTrigger>
                </Style.Triggers>
            </Style>
        </TextBlock.Style>
    </TextBlock>
</Grid>

First we wrap everthing in a Grid. We'll use this as a container to define our overall layout. Then we add our TextBox for user input, and our TextBlock as our watermark. Since we don't specify row and column definitions, these controls will overlap - and we want that; a watermark should visually appear on top of a textbox. On our TextBlock however, we don't want it be included in any hit test results, so we'll set the IsHitTestVisible property to false.

For the TextBlock's style, we'll default it to collapsed, and then set it to visible when our DataContext's Text property does not have content AND when the TextBox does not have keyboard focus.

And that's it! No converters, no extensions, just pure XAML.

Credits

History

2015-03-04 : Initial post

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here