Watermark Behavior for Textbox

It is obvious that there is no direct way to set Watermark in WPF textboxes. Some third party controls and codeplex gave extended textboxes which supports watermark. Watermark can also be achieved through overriding the default style of a textbox. A textblock/Label needs to be inserted in default control template to display the Watermark. But it will be a static one. To make it dynamic, developers used Tag property to store Watermark data.

But here is a behavior, which creates an adorner on top of Textbox. The adorner is responsible to draw the Watermark text. Font related dependency properties can be added to the behavior. So this is highly dynamic.


        public class WaterMarkAdorner : Adorner
        {
            private string text;
            private double fontSize;
            private string fontFamily;
            private Brush foreground;

            public WaterMarkAdorner(UIElement element, string text, double fontsize, string font, Brush foreground)
                : base(element)
            {
                this.IsHitTestVisible = false;
                this.Opacity = 0.6;
                this.text = text;
                this.fontSize = fontsize;
                this.fontFamily = font;
                this.foreground = foreground;
            }

            protected override void OnRender(System.Windows.Media.DrawingContext drawingContext)
            {
                base.OnRender(drawingContext);
                var text = new FormattedText(
                        this.text,
                        System.Globalization.CultureInfo.CurrentCulture,
                        System.Windows.FlowDirection.LeftToRight,
                        new System.Windows.Media.Typeface(fontFamily),
                        fontSize,
                        foreground);

                drawingContext.DrawText(text, new Point(3, 3));
            }
        }

The behavior utilizing this adorner to decorate the textbox. Right now the behavior supports only TextBox. But still the idea can be extended to PasswordBox, ComboBox, etc.

        private void OnLoaded(object sender, RoutedEventArgs e)
        {
            if (!this.AssociatedObject.IsFocused)
            {
                if (String.IsNullOrEmpty(this.AssociatedObject.Text))
                {
                    var layer = AdornerLayer.GetAdornerLayer(this.AssociatedObject);
                    layer.Add(adorner);
                }
            }
        }

The XAML code looks as follows,

            <TextBox Width="200"
                     Margin="5"
                     Height="20">
                <i:Interaction.Behaviors>
                    <behavior:WatermarkBehavior Text="Maximum 15 characters" />
                </i:Interaction.Behaviors>
            </TextBox>

watermark

Download Demo

2 thoughts on “Watermark Behavior for Textbox

Add yours

Leave a comment

Up ↑