天天看點

帶有提示文字的Textbox和PasswordBox

有時候項目中會遇到需要提示資訊的文本框和密碼框。例如登入的時候提升“請輸入密碼”“請輸入登入名之類的”。在這兒就寫一下,以備将來查用。

首先來看一下帶提示的TextBox:

首先,在項目中建立一個使用者控件,

xaml如下:

<TextBox x:Class="SampleControls.Controls.HintTextbox"

             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

             mc:Ignorable="d" x:Name="textBox"

             d:DesignHeight="300" d:DesignWidth="300">

    <TextBox.Resources>

        <VisualBrush x:Key="HelpBrush" TileMode="None" Opacity="0.3" Stretch="None" AlignmentY="Center"  AlignmentX="Left" ViewportUnits="RelativeToBoundingBox">

            <VisualBrush.Viewport>

                <Rect X="0.01" Y="0" Width="1" Height="1" ></Rect>

            </VisualBrush.Viewport>

            <VisualBrush.Visual>

                <TextBlock VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Grid.Column="1"  Text="{Binding Hint, ElementName=textBox}" Padding="10,0,0,0"

                           Width="{Binding ElementName=textBox,Path=ActualWidth}"/>

            </VisualBrush.Visual>

        </VisualBrush>

    </TextBox.Resources>

    <TextBox.Style>

        <Style TargetType="TextBox">

            <Setter Property="Background" Value="{Binding ElementName=textBox, Path=Background}"></Setter>

            <Style.Triggers>

                <Trigger Property="Text" Value="{x:Null}">

                    <Setter Property="Background" Value="{StaticResource HelpBrush}"/>

                </Trigger>

                <Trigger Property="Text" Value="">

                    <Setter Property="Background" Value="{StaticResource HelpBrush}"/>

                </Trigger>

            </Style.Triggers>

        </Style>

    </TextBox.Style>

</TextBox>

對應的.cs内容如下

public partial class HintTextbox : TextBox

    {

        public HintTextbox()

        {

            InitializeComponent();

        }

        /// <summary>

        /// 文本框提示文字

        /// </summary>

        public string Hint

        {

            get { return (string)GetValue(HintProperty); }

            set { SetValue(HintProperty, value); }

        }

        // Using a DependencyProperty as the backing store for Hint.  This enables animation, styling, binding, etc...

        public static readonly DependencyProperty HintProperty =

            DependencyProperty.Register("Hint", typeof(string), typeof(HintTextbox), new PropertyMetadata(null));

    }

PasswordBox

因為passwordBox中的Password不是依賴屬性,是以有的時候需要綁定的時候就沒法 實作,在這兒定義一個附加屬性來實作綁定,

public class PasswordBoxHelper

    {

        public static bool GetIsPasswordBindingEnabled(DependencyObject obj)

        {

            return (bool)obj.GetValue(IsPasswordBindingEnabledProperty);

        }

        public static void SetIsPasswordBindingEnabled(DependencyObject obj, bool value)

        {

            obj.SetValue(IsPasswordBindingEnabledProperty, value);

        }

        // Using a DependencyProperty as the backing store for IsPasswordBindingEnabled.  This enables animation, styling, binding, etc...

        public static readonly DependencyProperty IsPasswordBindingEnabledProperty =

            DependencyProperty.RegisterAttached("IsPasswordBindingEnabled", typeof(bool),

            typeof(PasswordBoxHelper),

            new UIPropertyMetadata(false, OnIsPasswordBindingEnableChanged));

        private static void OnIsPasswordBindingEnableChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

        {

            PasswordBox passwordBox = d as PasswordBox;

            if (passwordBox != null)

            {

                passwordBox.PasswordChanged -= passwordBox_PasswordChanged;

                if ((bool)e.NewValue)

                {

                    passwordBox.PasswordChanged += passwordBox_PasswordChanged;

                }

            }

        }

        static void passwordBox_PasswordChanged(object sender, RoutedEventArgs e)

        {

            PasswordBox passwordBox = (PasswordBox)sender;

            if (!string.Equals(GetBindedPassword(passwordBox), passwordBox.Password))

            {

                SetBindedPassword(passwordBox, passwordBox.Password);

            }

        }

        public static string GetBindedPassword(DependencyObject obj)

        {

            return (string)obj.GetValue(BindedPasswordProperty);

        }

        public static void SetBindedPassword(DependencyObject obj, string value)

        {

            obj.SetValue(BindedPasswordProperty, value);

        }

        // Using a DependencyProperty as the backing store for BindedPassword.  This enables animation, styling, binding, etc...

        public static readonly DependencyProperty BindedPasswordProperty =

            DependencyProperty.RegisterAttached("BindedPassword",

            typeof(string), typeof(PasswordBoxHelper),

            new UIPropertyMetadata(string.Empty, OnBindedPasswordChanged));

        private static void OnBindedPasswordChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

        {

            PasswordBox passwordBox = d as PasswordBox;

            if (passwordBox != null && !string.Equals(GetBindedPassword(passwordBox), passwordBox.Password))

            {

                passwordBox.Password = e.NewValue == null ? string.Empty : e.NewValue.ToString();

            }

        }

然後同樣定義一個使用者控件

xaml如下:

<UserControl x:Class="SampleControls.Controls.HintPasswordBox"

             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"

             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"

             xmlns:help="clr-namespace:SampleControls.Help"

             mc:Ignorable="d" x:Name="uc"

             d:DesignHeight="300" d:DesignWidth="300">

    <Grid>

        <PasswordBox x:Name="password" help:PasswordBoxHelper.IsPasswordBindingEnabled="true" FontSize="{Binding ElementName=uc,Path=FontSize}"

                     help:PasswordBoxHelper.BindedPassword="{Binding Path=Password,ElementName=uc,Mode=TwoWay}">

            <PasswordBox.Background>

                <VisualBrush TileMode="None" Opacity="0.3" Stretch="None" AlignmentY="Center"  AlignmentX="Left" ViewportUnits="RelativeToBoundingBox">

                    <VisualBrush.Viewport>

                        <Rect X="0.01" Y="0" Width="1" Height="1" ></Rect>

                    </VisualBrush.Viewport>

                    <VisualBrush.Visual>

                        <TextBlock VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Grid.Column="1"  Text="{Binding HintText, ElementName=uc}" Padding="10,0,0,0"

                           Width="{Binding ElementName=uc,Path=ActualWidth}" FontSize="{Binding ElementName=uc,Path=FontSize}"/>

                    </VisualBrush.Visual>

                </VisualBrush>

            </PasswordBox.Background>

        </PasswordBox>

    </Grid>

</UserControl>

.cs如下:

 public partial class HintPasswordBox : UserControl

    {

        public HintPasswordBox()

        {

            InitializeComponent();

        }

        public string Hint

        {

            get { return (string)GetValue(HintProperty); }

            set { SetValue(HintProperty, value); }

        }

        // Using a DependencyProperty as the backing store for Hit.  This enables animation, styling, binding, etc...

        public static readonly DependencyProperty HintProperty =

            DependencyProperty.Register("Hint", typeof(string), typeof(HintPasswordBox), new PropertyMetadata(null, new PropertyChangedCallback(OnHintChanged)));

        private static void OnHintChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

        {

            HintPasswordBox password = d as HintPasswordBox;

            password.UpdateStates();

        }

        public string HintText

        {

            get { return (string)GetValue(HintTextProperty); }

            set { SetValue(HintTextProperty, value); }

        }

        // Using a DependencyProperty as the backing store for HintText.  This enables animation, styling, binding, etc...

        public static readonly DependencyProperty HintTextProperty =

            DependencyProperty.Register("HintText", typeof(string), typeof(HintPasswordBox), new PropertyMetadata(null));

        public string Password

        {

            get { return (string)GetValue(PasswordProperty); }

            set { SetValue(PasswordProperty, value); }

        }

        // Using a DependencyProperty as the backing store for Password.  This enables animation, styling, binding, etc...

        public static readonly DependencyProperty PasswordProperty =

            DependencyProperty.Register("Password", typeof(string), typeof(HintPasswordBox), new PropertyMetadata(null, new PropertyChangedCallback(OnPasswordChanged)));

        private static void OnPasswordChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)

        {

            HintPasswordBox uc = d as HintPasswordBox;

            uc.UpdateStates();

        }

        private void UpdateStates()

        {

            if (string.IsNullOrWhiteSpace(Password))

            {

                HintText = Hint;

            }

            else

            {

                HintText = "";

            }

        }

  源代碼:http://download.csdn.net/detail/yulongguiziyao/8352581

繼續閱讀