» » » Пишем свой Watermark TextBox и PasswordBox для Win8/RT, Windows Phone

 

Пишем свой Watermark TextBox и PasswordBox для Win8/RT, Windows Phone

Автор: admin от 31-08-2017, 17:31, посмотрело: 2509

Сабж


На самом деле очень тревиальная задача, но, столкнувшись с которой, можно потерять драгоценное время.
Итак, что мы имеем:
WinRT XAML Toolkit несет на своем борту Watermark TextBox, но имеет ограниченый функционал (цветовое оформление Watermarkа). Вдобавок отсутсвие Watermark PasswordBox огорчает.
Следуйщий текст позволит Вам сэкономить 30 минут времении, имплементировав и настроив парочку простеньких контролов). Если интересно — добро пожаловать под кат.

Идея


Идея крайне проста: TextBox для ввода текста и TextBlock для отображения Watermark. (PasswordBox и TextBlock соответсвенно). Осталось только хитро манипулировать с прозрачностью контролов.
Представленный пример предназначен для Windows 8/RT. Имплементировать для Windows Phone не составит труда.

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
    }


И простое использование в любом нужном месте:





Только не забываем любимую строчку:

xmlns:controls="using:Test.Controls"


Как это работает?

При получении GotFocus/LostFocus обрабатываются при начале/окончании ввода текста/пароля. На основании введенных значений делается выбор об отображении Текста либо Watermark (метод CheckWatermark). При вводе текста/пароля в соответсующее поле перенаправляем в наше созданную DependencyProperty (методы Tb_OnTextChanged/Pb_OnTextChanged). Небольшой список DependencyProperty включает в себя текст Watermark, текст основного поля ввода, размер шрифта метки и текста.

Продолжаем подстраивать под себя

Совсем не сложно добавить любое необходимое свойство по Вашему вкусу. Потратили 10 минут, но получили полный контроль. Надеюсь сэкономил кому-нибудь время.

Note

Во время написания статьи наткнулся на Dependency Property Generator. Надеюсь это тоже будет экономить время.

Объективная/необъективная критика приветсвуется.



Категория: Операционные системы » Windows

Уважаемый посетитель, Вы зашли на сайт как незарегистрированный пользователь.
Мы рекомендуем Вам зарегистрироваться либо войти на сайт под своим именем.

Добавление комментария

Имя:*
E-Mail:
Комментарий:
Полужирный Наклонный текст Подчеркнутый текст Зачеркнутый текст | Выравнивание по левому краю По центру Выравнивание по правому краю | Вставка смайликов Выбор цвета | Скрытый текст Вставка цитаты Преобразовать выбранный текст из транслитерации в кириллицу Вставка спойлера
Введите два слова, показанных на изображении: *