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

本文共 3175 字,大约阅读时间需要 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 });
        }
posted on
2019-04-02 16:34 阅读(
...) 评论(
...)

转载于:https://www.cnblogs.com/lonelyxmas/p/10643486.html

你可能感兴趣的文章
正则表达式之 数据验证 与 文本替换
查看>>
linux 安装mysql数据库——yum安装法
查看>>
Visual Studio 2008 不能更改安装目录的原因
查看>>
Oracle之存储过程
查看>>
解决电脑复选框图标不正确方法
查看>>
伪数组怎么转为真正的数组呢~
查看>>
WebGL笔记(六):简单灯光
查看>>
XCode: duplicate symbol 解决方案
查看>>
关于求最大公约数
查看>>
【转载】Visual Studio2017如何打包发布Winform窗体程序
查看>>
【转载】通过搜狗站长平台提交网站域名变更后的文章地址
查看>>
【转载】Visual Studio2017中如何设置解决方案中的某个项目为启动项目
查看>>
hdu 1846 Brave Game
查看>>
数据库连接历险记
查看>>
抛弃msvcrtXX库
查看>>
血眼龙王传--秋叶青篇
查看>>
Runtime
查看>>
取消git忽略文件
查看>>
Leetcode2--->链表中对应位相加(进位)
查看>>
PXE远程自动安装操作系统
查看>>