How can I put some text into a TextBox which is removed automatically when user types something in it?
You can create a watermark that can be added to any TextBox
with an Attached Property. Here is the source for the Attached Property:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Documents;
///
/// Class that provides the Watermark attached property
///
public static class WatermarkService
{
///
/// Watermark Attached Dependency Property
///
public static readonly DependencyProperty WatermarkProperty = DependencyProperty.RegisterAttached(
"Watermark",
typeof(object),
typeof(WatermarkService),
new FrameworkPropertyMetadata((object)null, new PropertyChangedCallback(OnWatermarkChanged)));
#region Private Fields
///
/// Dictionary of ItemsControls
///
private static readonly Dictionary
The Attached Property uses a class called WatermarkAdorner
, here is that source:
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Media;
///
/// Adorner for the watermark
///
internal class WatermarkAdorner : Adorner
{
#region Private Fields
///
/// that holds the watermark
///
private readonly ContentPresenter contentPresenter;
#endregion
#region Constructor
///
/// Initializes a new instance of the class
///
/// to be adorned
/// The watermark
public WatermarkAdorner(UIElement adornedElement, object watermark) :
base(adornedElement)
{
this.IsHitTestVisible = false;
this.contentPresenter = new ContentPresenter();
this.contentPresenter.Content = watermark;
this.contentPresenter.Opacity = 0.5;
this.contentPresenter.Margin = new Thickness(Control.Margin.Left + Control.Padding.Left, Control.Margin.Top + Control.Padding.Top, 0, 0);
if (this.Control is ItemsControl && !(this.Control is ComboBox))
{
this.contentPresenter.VerticalAlignment = VerticalAlignment.Center;
this.contentPresenter.HorizontalAlignment = HorizontalAlignment.Center;
}
// Hide the control adorner when the adorned element is hidden
Binding binding = new Binding("IsVisible");
binding.Source = adornedElement;
binding.Converter = new BooleanToVisibilityConverter();
this.SetBinding(VisibilityProperty, binding);
}
#endregion
#region Protected Properties
///
/// Gets the number of children for the .
///
protected override int VisualChildrenCount
{
get { return 1; }
}
#endregion
#region Private Properties
///
/// Gets the control that is being adorned
///
private Control Control
{
get { return (Control)this.AdornedElement; }
}
#endregion
#region Protected Overrides
///
/// Returns a specified child for the parent .
///
/// A 32-bit signed integer that represents the index value of the child . The value of index must be between 0 and - 1.
/// The child .
protected override Visual GetVisualChild(int index)
{
return this.contentPresenter;
}
///
/// Implements any custom measuring behavior for the adorner.
///
/// A size to constrain the adorner to.
/// A object representing the amount of layout space needed by the adorner.
protected override Size MeasureOverride(Size constraint)
{
// Here's the secret to getting the adorner to cover the whole control
this.contentPresenter.Measure(Control.RenderSize);
return Control.RenderSize;
}
///
/// When overridden in a derived class, positions child elements and determines a size for a derived class.
///
/// The final area within the parent that this element should use to arrange itself and its children.
/// The actual size used.
protected override Size ArrangeOverride(Size finalSize)
{
this.contentPresenter.Arrange(new Rect(finalSize));
return finalSize;
}
#endregion
}
Now you can put a watermark on any TextBox like this:
Type here to search text
The watermark can be anything you want (text, images ...). In addition to working for TextBoxes, this watermark also works for ComboBoxes and ItemControls.
This code was adapted from this blog post.