前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >WPF Textbox设置Placeholder

WPF Textbox设置Placeholder

作者头像
码客说
发布2023-02-10 14:38:19
1.7K0
发布2023-02-10 14:38:19
举报
文章被收录于专栏:码客码客

前言

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

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

方式1 使用附加属性

添加引用

代码语言:javascript
复制
xmlns:local="clr-namespace:ZView"

使用方式

代码语言:javascript
复制
<TextBox
         Padding="6"
         VerticalContentAlignment="Center"
         FontSize="18"
         Foreground="gray"
         local:PlaceholderManager.Placeholder="请输入密钥"
         Text=""
         VerticalScrollBarVisibility="Disabled" />

添加类PlaceholderManager

代码语言:javascript
复制
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;

namespace ZView
{
  /// <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 TextBox();
        var binding = new Binding
        {
          Source = txt,
          //绑定到附加属性
          Path = new PropertyPath("(0)", PlaceholderProperty)
        };
        placeholderTextBlock.SetBinding(TextBox.TextProperty, binding);
        //placeholderTextBlock.FontStyle = FontStyles.Italic;
        placeholderTextBlock.Opacity = 0.8;
        placeholderTextBlock.Padding = new Thickness(10, 0, 0, 0);
        placeholderTextBlock.BorderThickness = new Thickness(0, 0, 0, 0);
        placeholderTextBlock.Foreground = Brushes.Gray;

        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 tb = sender as TextBox;
      if ((tb != null) && (TxtBrushes.ContainsKey(tb)))
      {
        var placeholderVisualBrush = TxtBrushes[tb];
        tb.Background = string.IsNullOrEmpty(tb.Text) ? placeholderVisualBrush : null;
      }
    }

    /// <summary>
    /// 文本框卸载的响应
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    private static void PlaceholderTextBox_Unloaded(object sender, RoutedEventArgs e)
    {
      var tb = sender as TextBox;
      if ((tb != null) && (TxtBrushes.ContainsKey(tb)))
      {
        TxtBrushes.Remove(tb);

        tb.TextChanged -= PlaceholderTextBox_TextChanged;
        tb.Unloaded -= PlaceholderTextBox_Unloaded;
      }
    }

    #endregion Events Handling
  }
}

方式2 使用自定义组件

使用方式

代码语言:javascript
复制
<local:PlaceholderTextBox
                          Padding="6"
                          VerticalContentAlignment="Center"
                          FontSize="18"
                          Foreground="gray"
                          Placeholder="请输入密钥"
                          Text=""
                          TextWrapping="Wrap"
                          VerticalScrollBarVisibility="Disabled" />

自定义组件

代码语言:javascript
复制
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Media;

namespace ZView
{
    /// <summary>
    /// 带点位符的文本输入控件
    /// </summary>
    public class PlaceholderTextBox : TextBox
    {
        #region Fields

        /// <summary>
        /// 占位符的文本框
        /// </summary>
        private readonly TextBox _placeholderTextBlock = new TextBox();

        /// <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(TextBox.TextProperty, binding);
            //_placeholderTextBlock.FontStyle = FontStyles.Italic;
            _placeholderTextBlock.Padding = new Thickness(10, 0, 0, 0);
            _placeholderTextBlock.BorderThickness = new Thickness(0, 0, 0, 0);
            _placeholderTextBlock.Foreground = Brushes.Gray;

            _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
    }
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-02-06,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 方式1 使用附加属性
  • 方式2 使用自定义组件
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档