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

目录
相关文章
WPF—多重绑定和跨层级绑定
WPF—多重绑定和跨层级绑定
|
C# 数据格式 XML
WPF 资源(StaticResource 静态资源、DynamicResource 动态资源、添加二进制资源、绑定资源树)
原文:WPF 资源(StaticResource 静态资源、DynamicResource 动态资源、添加二进制资源、绑定资源树) 一、WPF对象级(Window对象)资源的定义与查找 实例一: StaticR...
8356 0
|
C# 数据库
WPF中DataGrid控件绑定数据源
WPF中DataGrid控件绑定数据源
155 0
|
C#
WPF更新绑定字段
WPF更新绑定字段
97 0
|
前端开发 C#
WPF 之 数据与命令绑定 (MVVM方式)
WPF 之 数据与命令绑定 (MVVM方式)
191 0
WPF 之 数据与命令绑定 (MVVM方式)
|
C#
WPF 绑定父类属性
原文:WPF 绑定父类属性 1.绑定父控件的属性. 1 2 3 4 5 6 7 8 9 发现问题,父控件的属性如果是后期加载的,别如说Width或者Height不是固定的数值,那么绑定时没有效果的。
1267 0
|
C# 前端开发
wpf中的datagrid绑定操作按钮是否显示或者隐藏
如图,需要在wpf中的datagrid的操作那列有个确认按钮,然后在某些条件下确认按钮可见,某些情况下不可见的,放在mvc里直接在cshtml页面中if..else就行了。 但是在wpf里不行。。网上搜索了好久才找到解决方法,原来只是binding那个visiable属性就行了,
6887 0
|
C# .NET 开发框架
WPF笔记 ( xmlns引用,Resource、Binding 前/后台加载,重新绑定) 2013.6.7更新
原文:WPF笔记 ( xmlns引用,Resource、Binding 前/后台加载,重新绑定) 2013.6.7更新 1、xmlns Mapping URI的格式是 clr-namespace:[;assembly=] (1)如果自定义类和XAML处在同一个Assembly之中,只还需要提供clr-namespace值。
1443 0
|
C#
潜移默化学会WPF(难点控件treeview)--改造TreeView(CheckBox多选择版本),递归绑定数据
原文:潜移默化学会WPF(难点控件treeview)--改造TreeView(CheckBox多选择版本),递归绑定数据 目前自己对treeview的感慨很多 今天先讲 面对这种 表结构的数据 的其中一种绑定方法,后面多几列其他属性都没关系,例如多个字段, 1  A  0 2  B  0 3  C  0 4  D  1 5  E  2 6  F  4 7  G 1 .
2361 0
|
C# 容器 存储
WPF元素绑定
原文:WPF元素绑定 数据绑定简介:数据绑定是一种关系,该关系告诉WPF从源对象提取一些信息,并用这些信息设置目标对象的属性。目标属性是依赖项属性。源对象可以是任何内容,从另一个WPF元素乃至ADO.NET数据对象(如DataTable)或自行创建出数据对象。
867 0