您的位置:首页 > 其它

[WPF]实现密码框的密码绑定

2009-08-27 11:44 309 查看
                                                 [WPF]实现密码框的密码绑定

                                                           周银辉

正如绑定TextBox控件的Text属性一样, 我们希望能够将PasswordBox空间的Password属性进行绑定, 比如在MVVM模式中,这似乎是必须的, 但可惜的是, Password属性是不支持绑定的(不是依赖属性, 也没有实现INotifyPropertyChanged).

这可能是出于安全性的考虑. 但在我们的系统为了实现View层密码框中的密码与后台其它层之间的密码属性之间的绑定, 可以采取如下思路: 将密码框的密码和某一个缓冲区进行同步, 缓冲区在和后台进行绑定. 其中密码框与缓冲区之间的同步可采用事件进行通知, 并将缓冲区打造成依赖属性, 然后缓冲区就支持绑定了, 并给后台提供正确的密码.

缓冲区可以是哈希表或其他字典结构, 以便将密码框和缓冲区中的密码一 一对应起来, 也可以使AttachProperty(附加属性), 其实附加属性的机制也就是对缓存了的一个大字典进行操作

    public static class PasswordBoxBindingHelper

    {

        public static bool GetIsPasswordBindingEnabled(DependencyObject obj)

        {

            return (bool)obj.GetValue(IsPasswordBindingEnabledProperty);

        }

        public static void SetIsPasswordBindingEnabled(DependencyObject obj, bool value)

        {

            obj.SetValue(IsPasswordBindingEnabledProperty, value);

        }

        public static readonly DependencyProperty IsPasswordBindingEnabledProperty =

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

            typeof(PasswordBoxBindingHelper), 

            new UIPropertyMetadata(false, OnIsPasswordBindingEnabledChanged));

        private static void OnIsPasswordBindingEnabledChanged(DependencyObject obj, 

                                                              DependencyPropertyChangedEventArgs e)

        {

            var passwordBox = obj as PasswordBox;

            if(passwordBox != null)

            {

                passwordBox.PasswordChanged -= PasswordBoxPasswordChanged;

                if ((bool)e.NewValue)

                {

                    passwordBox.PasswordChanged += PasswordBoxPasswordChanged;

                }

               

            }

        }

        //when the passwordBox's password changed, update the buffer
        static void PasswordBoxPasswordChanged(object sender, RoutedEventArgs e)

        {

            var 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);

        }

        public static readonly DependencyProperty BindedPasswordProperty =

            DependencyProperty.RegisterAttached("BindedPassword", typeof(string), 

            typeof(PasswordBoxBindingHelper), 

            new UIPropertyMetadata(string.Empty, OnBindedPasswordChanged));

        //when the buffer changed, upate the passwordBox's password
        private static void OnBindedPasswordChanged(DependencyObject obj, 

                                                    DependencyPropertyChangedEventArgs e)

        {

            var passwordBox = obj as PasswordBox;

            if (passwordBox != null)

            {

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

            }

        }       

    }

在View层, 如下使用便可以了:
<PasswordBox  Helpers:PasswordBoxBindingHelper.IsPasswordBindingEnabled="True" 

                     Helpers:PasswordBoxBindingHelper.BindedPassword=

                     "{Binding Path=Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

另外, 在更改了密码框的密码后, 需要手动更新密码框插入符(CaretIndex)的位置, 可惜的是, 密码框并没有给我们提供这样的属性或方法(TextBox有, PasswordBox没有), 可以采用下面的方法来设置:
        private static void SetPasswordBoxSelection(PasswordBox passwordBox, int start, int length)
        {
            var select = passwordBox.GetType().GetMethod("Select", 
                            BindingFlags.Instance | BindingFlags.NonPublic);

            select.Invoke(passwordBox, new object[] { start, length });
        }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  wpf textbox string null