你的位置:首页 > ASP.net教程

[ASP.net教程]WPF带占位符的TextBox


简介

效果图如下:

1

使用的XAML代码如下:

<Window x:Class="PlaceHolderTextBox.MainWindow"    ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    ="http://schemas.microsoft.com/winfx/2006/xaml"    ="clr-namespace:PlaceHolderTextBox"    Title="MainWindow"    Width="525"    Height="350">  <StackPanel>    <local:PlaceholderTextBox Placeholder="查询" />    <TextBox x:Name="TxtTest" local:PlaceholderHelper.Placeholder="搜索" />  </StackPanel></Window>

其中第一个是带占位符的文本框,第二个使用附加属性装饰在现有的文本框上。

原理

将一个与占位符绑定的TextBlock放入VisualBrush内,在TextBox的Text为空时使用VisualBrush绘制背景,不为空时背景设为Null。

正因为如此,如果文本框设置了背景,使用此方法就会覆盖原有的背景。但一般不会设置TextBox的背景。

带占位符的文本框

代码较简单,如下:

using System.Globalization;using System.Windows;using System.Windows.Controls;using System.Windows.Data;using System.Windows.Media;namespace PlaceHolderTextBox{  /// <summary>  /// 带点位符的文本输入控件  /// </summary>  public class PlaceholderTextBox:TextBox  {    #region Fields    /// <summary>    /// 占位符的文本框    /// </summary>    private readonly TextBlock _placeholderTextBlock = new TextBlock();    /// <summary>    /// 占位符的画刷    /// </summary>    private readonly VisualBrush _placeholderVisualBrush = new VisualBrush();    #endregion Fields    #region Properties    /// <summary>    /// 占位符的依赖属性    /// </summary>    public static readonly DependencyProperty PlaceholderProperty = DependencyProperty.Register(      "Placeholder", typeof (string), typeof (PlaceholderTextBox),      new FrameworkPropertyMetadata("请在此输入", FrameworkPropertyMetadataOptions.AffectsRender));    /// <summary>    /// 占位符    /// </summary>    public string Placeholder    {      get { return (string) GetValue(PlaceholderProperty); }      set { SetValue(PlaceholderProperty, value); }    }    #endregion Properties    #region Public Methods    public PlaceholderTextBox()    {      var binding = new Binding      {        Source = this,        Path = new PropertyPath("Placeholder")      };      _placeholderTextBlock.SetBinding(TextBlock.TextProperty, binding);      _placeholderTextBlock.FontStyle = FontStyles.Italic;      _placeholderVisualBrush.AlignmentX = AlignmentX.Left;      _placeholderVisualBrush.Stretch = Stretch.None;      _placeholderVisualBrush.Visual = _placeholderTextBlock;      Background = _placeholderVisualBrush;      TextChanged += PlaceholderTextBox_TextChanged;    }    #endregion Public Methods    #region Events Handling    /// <summary>    /// 文本变化的响应    /// </summary>    /// <param name="sender"></param>    /// <param name="e"></param>    private void PlaceholderTextBox_TextChanged(object sender, TextChangedEventArgs e)    {      Background = string.IsNullOrEmpty(Text) ? _placeholderVisualBrush : null;    }    #endregion Events Handling  }}

使用附加属性

代码较简单,如下:

using System.Collections.Generic;using System.Windows;using System.Windows.Controls;using System.Windows.Data;using System.Windows.Media;namespace PlaceHolderTextBox{  /// <summary>  /// 占位符的管理类  /// </summary>  public class PlaceholderHelper : TextBox  {    #region Fields    /// <summary>    /// 文本框和Visual画刷对应的字典    /// </summary>    private static readonly Dictionary<TextBox, VisualBrush> TxtBrushes = new Dictionary<TextBox, VisualBrush>();    #endregion Fields    #region Attached DependencyProperty    /// <summary>    /// 占位符的附加依赖属性    /// </summary>    public static readonly DependencyProperty PlaceholderProperty = DependencyProperty.RegisterAttached(      "Placeholder", typeof(string), typeof(PlaceholderHelper),      new PropertyMetadata("请在此处输入", OnPlaceholderChanged));    /// <summary>    /// 获取占位符    /// </summary>    /// <param name="obj">占位符所在的对象</param>    /// <returns>占位符</returns>    public static string GetPlaceholder(DependencyObject obj)    {      return (string)obj.GetValue(PlaceholderProperty);    }    /// <summary>    /// 设置占位符    /// </summary>    /// <param name="obj">占位符所在的对象</param>    /// <param name="value">占位符</param>    public static void SetPlaceholder(DependencyObject obj, string value)    {      obj.SetValue(PlaceholderProperty, value);    }    #endregion Attached DependencyProperty    #region Events Handling    /// <summary>    /// 占位符改变的响应    /// </summary>    /// <param name="d">来源</param>    /// <param name="e">改变信息</param>    public static void OnPlaceholderChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)    {      var txt = d as TextBox;      if ((txt != null) && (!TxtBrushes.ContainsKey(txt)))      {        var placeholderTextBlock = new TextBlock();        var binding = new Binding        {          Source = txt,          //绑定到附加属性          Path = new PropertyPath("(0)", PlaceholderProperty)        };        placeholderTextBlock.SetBinding(TextBlock.TextProperty, binding);        placeholderTextBlock.FontStyle = FontStyles.Italic;        var placeholderVisualBrush = new VisualBrush        {          AlignmentX = AlignmentX.Left,          Stretch = Stretch.None,          Visual = placeholderTextBlock        };        txt.Background = placeholderVisualBrush;        txt.TextChanged += PlaceholderTextBox_TextChanged;        txt.Unloaded += PlaceholderTextBox_Unloaded;        TxtBrushes.Add(txt, placeholderVisualBrush);      }    }    /// <summary>    /// 文本变化的响应    /// </summary>    /// <param name="sender"></param>    /// <param name="e"></param>    private static void PlaceholderTextBox_TextChanged(object sender, TextChangedEventArgs e)    {      var txt = sender as TextBox;      if ((txt != null) && (TxtBrushes.ContainsKey(txt)))      {        var placeholderVisualBrush = TxtBrushes[txt];        txt.Background = string.IsNullOrEmpty(txt.Text) ? placeholderVisualBrush : null;      }    }    /// <summary>    /// 文本框卸载的响应    /// </summary>    /// <param name="sender"></param>    /// <param name="e"></param>    private static void PlaceholderTextBox_Unloaded(object sender, RoutedEventArgs e)    {      var txt = sender as TextBox;      if ((txt != null) && (TxtBrushes.ContainsKey(txt)))      {        TxtBrushes.Remove(txt);        txt.TextChanged -= PlaceholderTextBox_TextChanged;        txt.Unloaded -= PlaceholderTextBox_Unloaded;      }    }    #endregion Events Handling  }}