WPF帶占位符的TextBox
阿新 • • 發佈:2019-01-11
bind controls tex ros local amp fec www. 效果圖 原文:WPF帶占位符的TextBox
簡介
效果圖如下:
使用的XAML代碼如下:
<Window x:Class="PlaceHolderTextBox.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:PlaceHolderTextBox" Title="MainWindow"Width="525" Height="350"> <StackPanel> <local:PlaceholderTextBox Placeholder="查詢" /> <TextBox x:Name="TxtTest" local:PlaceholderManager.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 PlaceholderManager { #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(PlaceholderManager), 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 } }
WPF帶占位符的TextBox