Click here to Skip to main content
15,891,423 members
Articles / Desktop Programming / WPF
Tip/Trick

XAML only WPF Watermarked TextBox

Rate me:
Please Sign up or sign in to vote.
4.93/5 (7 votes)
5 Mar 2015CPOL1 min read 30.4K   714   17  
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, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
United States United States
Matthew is a software developer currently living and working in San Antonio Texas. When not working on software, Matthew enjoys spending time in his backyard garden.

Comments and Discussions

 
-- There are no messages in this forum --