How To Create A Watermark/Placeholder Text Using Behavior In WPF

How To Create A Watermark/Placeholder Text Using Behavior In WPF

As we know in WPF there is no direct way to set Watermark to a TextBox. However, many times we may need to add a watermark to improve the user experience.

In WPF, we can create a watermark using

System.Windows.Interactivity.Behavior<T>

Here, the placeholder parameter <T> can be any UIElement you want the behavior to act on. For our purposes here, we will set it to TextBox i.e. Behavior<TextBox> because we are creating a watermark for TextBox.

Create a watermark behavior

Let's implement a simple behaviour which will set the watermark to a TextBox when it's Text property is null or does not hold any value, as well as the other way around.

    public class WatermarkBehavior : Behavior<TextBox>
    {
        private bool _hasWatermark;
        private Brush _textBoxForeground;

        public String Text { get; set; }
        public Brush Foreground { get; set; }

        protected override void OnAttached()
        {
            _textBoxForeground = AssociatedObject.Foreground;

            base.OnAttached();
            if (Text != null)
                SetWatermarkText();
            AssociatedObject.GotFocus += GotFocus;
            AssociatedObject.LostFocus += LostFocus;
        }

        private void LostFocus(object sender, RoutedEventArgs e)
        {
            if (AssociatedObject.Text.Length == 0)
                if (Text != null)
                    SetWatermarkText();
        }

        private void GotFocus(object sender, RoutedEventArgs e)
        {
            if (_hasWatermark)
                RemoveWatermarkText();
        }

        private void RemoveWatermarkText()
        {
            AssociatedObject.Foreground = _textBoxForeground;
            AssociatedObject.Text = "";
            _hasWatermark = false;
        }

        private void SetWatermarkText()
        {
            AssociatedObject.Foreground = Foreground;
            AssociatedObject.Text = Text;
            _hasWatermark = true;
        }

        protected override void OnDetaching()
        {
            base.OnDetaching();
            AssociatedObject.GotFocus -= GotFocus;
            AssociatedObject.LostFocus -= LostFocus;
        }
    }

Code explanation

Here, OnAttached is the method which is called when we activate the behavior by attaching it to any TextBox we like. We are also using it to subscribe LostFocus and GotFocus events.

So as soon as we attach the behavior to the TextBox it set the Watermark text.

AssociatedObject is the TextBox control (you can use other UI control also) to that the behavior has been applied.

LostFocus and GotFocus are the events used to set and remove Watermark text respectively.

OnDetaching is the method we are using to unsubscribe LostFocus and GotFocus events.

You can modify this behavior if you want to add more styling and etc. to the Watermark Text as per business need.

You can also create custom behavior for achieving many other goals like: for auto-scale a font-size (zoom in/out effect), to capitalize the first letter, and etc. The list of possible behaviors is very long.

You can see my below article for how to implement above behavior in XAML for adding watermark: