We write our Watermark TextBox and PasswordBox for Win8 / RT, Windows Phone

Subject


Actually, it’s a very troubling task, but, faced with which, you can lose precious time.
So, what we have:
WinRT XAML Toolkit carries a Watermark TextBox on its board, but has limited functionality (Watermark color scheme). In addition, the lack of Watermark PasswordBox upsets.
The following text will save you 30 minutes of time by implementing and setting up a couple of simple controls). If interested - welcome to cat.

Idea


The idea is extremely simple: TextBox for entering text and TextBlock for displaying Watermark. (PasswordBox and TextBlock respectively). It remains only to cunningly manipulate the transparency of controls.
The presented example is intended for Windows 8 / RT. Implementing for Windows Phone is easy.

WatermarkTextBox.xaml



WatermarkTextBox.cs

 public sealed partial class WatermarkTextBox : UserControl
    {
        public WatermarkTextBox()
        {
            InitializeComponent();
        }
        private void LostFocus(object sender, RoutedEventArgs e)
        {
            CheckWatermark();
            brd.Background = new SolidColorBrush(Color.FromArgb(255, 224, 224, 224));
        }
        public void CheckWatermark()
        {
            var passwordEmpty = string.IsNullOrEmpty(tb.Text);
            tbWatermark.Opacity = passwordEmpty ? 100 : 0;
            tb.Opacity = passwordEmpty ? 0 : 100;
        }
        private void GotFocus(object sender, RoutedEventArgs e)
        {
            tbWatermark.Opacity = 0;
            tb.Opacity = 100;
            brd.Background = new SolidColorBrush(Color.FromArgb(255, 255, 255, 255));
        }
        private void Tb_OnTextChanged(object sender, TextChangedEventArgs e)
        {
            Text = tb.Text;
        }
        #region DependencyProperty
        /// 
        /// Watermark
        /// 
        public string Watermark 
        {
            get { return (string)GetValue(WatermarkProperty); }
            set { SetValue(WatermarkProperty, value); }
        }
        public static readonly DependencyProperty WatermarkProperty = DependencyProperty.Register("Watermark", typeof(string), typeof(WatermarkTextBox), new PropertyMetadata("", WatermarkChanged));
        private static void WatermarkChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var controll = (WatermarkTextBox)d;
            var val = (string)e.NewValue;
            controll.tbWatermark.Text = val;
        }
        /// 
        /// TextSize
        /// 
        public int TextSize
        {
            get { return (int)GetValue(TextSizeProperty); }
            set { SetValue(TextSizeProperty, value); }
        }
        public static readonly DependencyProperty TextSizeProperty = DependencyProperty.Register("TextSize", typeof(int), typeof(WatermarkTextBox), new PropertyMetadata(0, TextSizeChanged));
        private static void TextSizeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var controll = (WatermarkTextBox)d;
            var val = (int)e.NewValue;
            if (val < 10){val = 10;}
            controll.tb.FontSize = val;
            controll.tbWatermark.FontSize = val;
        }
        /// 
        /// Text
        /// 
        public string Text
        {
            get { return (string)GetValue(TextProperty); }
            set { SetValue(TextProperty, value); }
        }
        public static readonly DependencyProperty TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(WatermarkTextBox), new PropertyMetadata("", TextChanged));
        private static void TextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var controll = (WatermarkTextBox)d;
            var val = (string)e.NewValue;
            if (val == null)
            {
                controll.tb.Text = "";
                return;
            }
            controll.tb.Text = val;
        }
        #endregion
    }


WatermarkPasswordBox.xaml

UserControl
    x:Class="Test.Controls.WatermarkPasswordBox"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    d:DesignHeight="300"
    d:DesignWidth="400">
    


WatermarkPasswordBox.cs

  public sealed partial class WatermarkPasswordBox : UserControl
    {
        public WatermarkPasswordBox()
        {
            this.InitializeComponent();
        }
        private void PasswordLostFocus(object sender, RoutedEventArgs e)
        {
            CheckWatermark();
            brd.Background = new SolidColorBrush(Color.FromArgb(255, 224, 224, 224));
        }
        public void CheckWatermark()
        {
            var passwordEmpty = string.IsNullOrEmpty(pb.Password);
            tbWatermark.Opacity = passwordEmpty ? 100 : 0;
            pb.Opacity = passwordEmpty ? 0 : 100;
        }
        private void PasswordGotFocus(object sender, RoutedEventArgs e)
        {
            tbWatermark.Opacity = 0;
            pb.Opacity = 100;
            brd.Background = new SolidColorBrush(Color.FromArgb(255, 255, 255, 255));
        }
        private void Pb_OnPasswordChanged(object sender, RoutedEventArgs e)
        {
            Password = pb.Password;
        }
        #region DependencyProperty
        /// 
        /// Watermark
        /// 
        public string Watermark
        {
            get { return (string)GetValue(WatermarkProperty); }
            set { SetValue(WatermarkProperty, value); }
        }
        public static readonly DependencyProperty WatermarkProperty = DependencyProperty.Register("Watermark", typeof(string), typeof(WatermarkPasswordBox), new PropertyMetadata("", WatermarkChanged));
        private static void WatermarkChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var controll = (WatermarkPasswordBox)d;
            var val = (string)e.NewValue;
            controll.tbWatermark.Text = val;
        }
        /// 
        /// Password
        /// 
        public string Password
        {
            get { return (string)GetValue(PasswordProperty); }
            set { SetValue(PasswordProperty, value); }
        }
        public static readonly DependencyProperty PasswordProperty = DependencyProperty.Register("Password", typeof(string), typeof(WatermarkPasswordBox), new PropertyMetadata("", PasswordChanged));
        private static void PasswordChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var controll = (WatermarkPasswordBox)d;
            var val = (string)e.NewValue;
            if (val == null)
            {
                controll.pb.Password = "";
                return;
            }
            controll.pb.Password = val;
        }
        /// 
        /// TextSize
        /// 
        public int TextSize
        {
            get { return (int)GetValue(TextSizeProperty); }
            set { SetValue(TextSizeProperty, value); }
        }
        public static readonly DependencyProperty TextSizeProperty = DependencyProperty.Register("TextSize", typeof(int), typeof(WatermarkPasswordBox), new PropertyMetadata(0, TextSizeChanged));
        private static void TextSizeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var controll = (WatermarkPasswordBox)d;
            var val = (int)e.NewValue;
            if (val < 10) { val = 10; }
            controll.pb.FontSize = val;
            controll.tbWatermark.FontSize = val;
        }
        #endregion
    }


And simple use anywhere you want:



Just do not forget your favorite line:

xmlns:controls="using:Test.Controls"


How it works?

Upon receipt, GotFocus / LostFocus are processed at the beginning / end of text / password input. Based on the entered values, a choice is made whether to display the Text or Watermark (CheckWatermark method). When entering text / password in the corresponding field, we redirect to our created DependencyProperty (Tb_OnTextChanged / Pb_OnTextChanged methods). A small list of DependencyProperty includes the text Watermark, the text of the main input field, the font size of the label and text.

We continue to adjust for ourselves

It is not at all difficult to add any necessary property to your taste. Spent 10 minutes, but got full control. I hope I saved someone time.

Note

While writing an article, I came across a Dependency Property Generator . Hope this saves time too.

Objective / biased criticism is welcome.

Update


The upper left is WatermarkTextBox The
lower left is WatermarkPasswordBox The
upper right is WatermarkTextBox with the entered data The
lower right is WatermarkPasswordBox with the entered data and focus.

Also popular now: