1. 程式人生 > >WPF帶占位符的TextBox

WPF帶占位符的TextBox

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