博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[WPF]实现密码框的密码绑定
阅读量:5782 次
发布时间:2019-06-18

本文共 3075 字,大约阅读时间需要 10 分钟。

原文:

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

转载地址:http://fqcyx.baihongyu.com/

你可能感兴趣的文章
python udp编程实例
查看>>
TortoiseSVN中图标的含义
查看>>
Tasks and Back stack 详解
查看>>
关于EXPORT_SYMBOL的作用浅析
查看>>
成功的背后!(给所有IT人)
查看>>
在SpringMVC利用MockMvc进行单元测试
查看>>
Nagios监控生产环境redis群集服务战
查看>>
Angular - -ngKeydown/ngKeypress/ngKeyup 键盘事件和鼠标事件
查看>>
Android BlueDroid(一):BlueDroid概述
查看>>
Java利用httpasyncclient进行异步HTTP请求
查看>>
宿舍局域网的应用
查看>>
html代码究竟什么用途
查看>>
Hadoop HDFS编程 API入门系列之路径过滤上传多个文件到HDFS(二)
查看>>
Python version 2.7 required, which was not foun...
查看>>
context:annotation-config vs component-scan
查看>>
exgcd、二元一次不定方程学习笔记
查看>>
经典sql
查看>>
CSS3边框会动的信封
查看>>
JavaWeb实例设计思路(订单管理系统)
查看>>
source insight中的快捷键总结
查看>>