在WPF的MVVM框架中实现对密码框的密码绑定(转)
2012-03-27 14:39
417 查看
正如绑定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 });
}
复制代码
这应该是出于安全性的考虑. 但在我们的系统为了实现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 });
}
复制代码
相关文章推荐
- MVVM设计模式和在WPF中的实现(四) 事件绑定
- WPF密码控件PasswordBox之 MVVM绑定使用
- WPF Prism框架下基于MVVM模式的命令、绑定、事件
- 们只是「电脑玩物」 首页 实用技巧 免费资源 超好玩的游戏 软件推荐 IT技术 资讯 编程 其它 MVVM设计模式和WPF中的实现(四) 事件绑定 07net01.com 发布于 2015-10-08
- [WPF]实现密码框的密码绑定
- WPF与MVVM的实现(二)数据绑定
- MVVM设计模式和WPF中的实现 (事件绑定)
- MVVM设计模式和WPF中的实现(四)事件绑定
- 实现了数据绑定 Presentation Model(MVVM) 模式的Android开源框架——RoboBinding
- MVVM模式解析和在WPF中的实现(三)命令绑定
- MVVM框架下,WPF实现Datagrid里的全选和选择
- MVVM模式和在WPF中的实现(二)数据绑定
- JavaScript中MVVM框架是如何实现双向绑定的
- RoboBinding:一个实现了数据绑定 Presentation Model(MVVM) 模式的Android开源框架
- WPF与MVVM的实现(四)命令绑定
- WPF与MVVM的实现(三)List的数据绑定
- [WPF]实现密码框的密码绑定
- [WPF]实现密码框的密码绑定
- 【我们一起写框架】MVVM的WPF框架(二)—绑定
- [WPF]实现密码框的密码绑定