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

简介: 原文:[WPF]实现密码框的密码绑定                                                 [WPF]实现密码框的密码绑定                                                            周银辉 正如...
原文: [WPF]实现密码框的密码绑定

                                                 [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 });
        }

目录
相关文章
|
10月前
|
C#
WPF文本框限制
WPF文本框限制
49 0
|
10月前
|
C#
WPF做登陆界面
WPF做登陆界面
|
C# 前端开发
wpf中的datagrid绑定操作按钮是否显示或者隐藏
如图,需要在wpf中的datagrid的操作那列有个确认按钮,然后在某些条件下确认按钮可见,某些情况下不可见的,放在mvc里直接在cshtml页面中if..else就行了。 但是在wpf里不行。。网上搜索了好久才找到解决方法,原来只是binding那个visiable属性就行了,
6848 0
|
C#
【WPF】绑定Hyperlink超链接
原文:【WPF】绑定Hyperlink超链接 Hyperlink超链接的简单使用 前台XAML: 说明文字: www.baidu.com 后台代码实现点击超链接的逻辑: private void Hyper...
1357 0
|
C#
WPF ListBoxItem模板中添加CheckBox选中问题
原文:WPF ListBoxItem模板中添加CheckBox选中问题 是这样的,需要一个ListBox来展示照片,并添加一个选中的CheckBox.
1600 0
|
C#
设置WPF输入框焦点
原文:设置WPF输入框焦点 在WPF中设置控件键盘焦点 Keyboard.Focus(/*控件名称*/);
1264 0
|
C#
WPF中一个控件绑定另一个控件的属性
原文:WPF中一个控件绑定另一个控件的属性 如同一个Grid中的一个按钮根据另一个按钮的显示与否作出不同的响应: 绑定的时候通过ElementName来指定控件               ...
1802 0
|
C# 存储
WPF用样式实现TextBox的虚拟提示效果
原文:WPF用样式实现TextBox的虚拟提示效果 【版权声明】本文为博主原创,未经允许禁止用作商业用途,如有转载请注明出处。  话说好多软件和网站都能实现虚拟提示,好吧这个名词是我自己起的,因为我也不知道这么形容这个效果。
1700 0