Watermark / hint text / placeholder TextBox

后端 未结 30 3096
遇见更好的自我
遇见更好的自我 2020-11-22 02:20

How can I put some text into a TextBox which is removed automatically when user types something in it?

30条回答
  •  说谎
    说谎 (楼主)
    2020-11-22 02:24

    @Veton - I really like the simplicity of your solution but my reputation isn't high enough to bump you yet.

    @Tim Murphy - That "Two-way binding requires Path or XPath" error was an easy fix... updated code including some other little tweaks (only WPF tested):

    using System;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Media;
    
    public class TextBoxWatermarked : TextBox
    {
      public string Watermark
      {
        get { return (string)GetValue(WaterMarkProperty); }
        set { SetValue(WaterMarkProperty, value); }
      }
      public static readonly DependencyProperty WaterMarkProperty =
          DependencyProperty.Register("Watermark", typeof(string), typeof(TextBoxWatermarked), new PropertyMetadata(new PropertyChangedCallback(OnWatermarkChanged)));
    
      private bool _isWatermarked = false;
      private Binding _textBinding = null;
    
      public TextBoxWatermarked()
      {
        Loaded += (s, ea) => ShowWatermark();
      }
    
      protected override void OnGotFocus(RoutedEventArgs e)
      {
        base.OnGotFocus(e);
        HideWatermark();
      }
    
      protected override void OnLostFocus(RoutedEventArgs e)
      {
        base.OnLostFocus(e);
        ShowWatermark();
      }
    
      private static void OnWatermarkChanged(DependencyObject sender, DependencyPropertyChangedEventArgs ea)
      {
        var tbw = sender as TextBoxWatermarked;
        if (tbw == null || !tbw.IsLoaded) return; //needed to check IsLoaded so that we didn't dive into the ShowWatermark() routine before initial Bindings had been made
        tbw.ShowWatermark();
      }
    
      private void ShowWatermark()
      {
        if (String.IsNullOrEmpty(Text) && !String.IsNullOrEmpty(Watermark))
        {
          _isWatermarked = true;
    
          //save the existing binding so it can be restored
          _textBinding = BindingOperations.GetBinding(this, TextProperty);
    
          //blank out the existing binding so we can throw in our Watermark
          BindingOperations.ClearBinding(this, TextProperty);
    
          //set the signature watermark gray
          Foreground = new SolidColorBrush(Colors.Gray);
    
          //display our watermark text
          Text = Watermark;
        }
      }
    
      private void HideWatermark()
      {
        if (_isWatermarked)
        {
          _isWatermarked = false;
          ClearValue(ForegroundProperty);
          Text = "";
          if (_textBinding != null) SetBinding(TextProperty, _textBinding);
        }
      }
    
    }
    

提交回复
热议问题