绑定密码





5.00/5 (8投票s)
绑定密码。
那些关注我的博客和与WPF信徒们交流的人都知道,我非常喜欢WPF的数据绑定功能,并且在绝大多数情况下,我对此都非常满意。 但在令人惊叹的绑定应用程序中,存在一个瑕疵,那就是PasswordBox
。 从表面上看,这个控件看起来像一个textbox
,但当你编写MVVM应用程序并像我一样依赖绑定时,就会出现问题;你无法将其绑定。 是的,你没听错,你无法使用PasswordBox
进行绑定。
缺乏绑定的原因很好理解——PasswordBox.Password
不是一个依赖属性,表面上是因为这会导致密码以明文形式存储在内存中,这存在潜在的安全隐患。 但是,如果你不太担心这个潜在的安全漏洞,那么有一个解决方法。 好消息,各位——以下类(取自我即将推出的Twitter客户端Songbird
)是一种使用PasswordBox
进行绑定的方法。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
namespace SongBird.Infrastructure
{
/// <summary>
/// This class adds binding capabilities to the standard WPF PasswordBox.
/// </summary>
public class BoundPasswordBox
{
#region BoundPassword
private static bool _updating = false;
/// <summary>
/// BoundPassword Attached Dependency Property
/// </summary>
public static readonly DependencyProperty BoundPasswordProperty =
DependencyProperty.RegisterAttached("BoundPassword",
typeof(string),
typeof(BoundPasswordBox),
new FrameworkPropertyMetadata(string.Empty, OnBoundPasswordChanged));
/// <summary>
/// Gets the BoundPassword property.
/// </summary>
public static string GetBoundPassword(DependencyObject d)
{
return (string)d.GetValue(BoundPasswordProperty);
}
/// <summary>
/// Sets the BoundPassword property.
/// </summary>
public static void SetBoundPassword(DependencyObject d, string value)
{
d.SetValue(BoundPasswordProperty, value);
}
/// <summary>
/// Handles changes to the BoundPassword property.
/// </summary>
private static void OnBoundPasswordChanged(
DependencyObject d,
DependencyPropertyChangedEventArgs e)
{
PasswordBox password = d as PasswordBox;
if (password != null)
{
// Disconnect the handler while we're updating.
password.PasswordChanged -= PasswordChanged;
}
if (e.NewValue != null)
{
if (!_updating)
{
password.Password = e.NewValue.ToString();
}
}
else
{
password.Password = string.Empty;
}
// Now, reconnect the handler.
password.PasswordChanged += new RoutedEventHandler(PasswordChanged);
}
/// <summary>
/// Handles the password change event.
/// </summary>
static void PasswordChanged(object sender, RoutedEventArgs e)
{
PasswordBox password = sender as PasswordBox;
_updating = true;
SetBoundPassword(password, password.Password);
_updating = false;
}
#endregion
}
}
使用它再简单不过了,只需在你的XAML中添加对namespace
的引用,并使用BoundPasswordBox
类更新你的PasswordBox
即可。 现在你拥有了一个可绑定的PasswordBox
。
<PasswordBox
Grid.Column="1"
Grid.Row="2"
Margin="5,5,5,5"
password:BoundPasswordBox.BoundPassword="{Binding Path=Password,
Mode=TwoWay,
UpdateSourceTrigger=PropertyChanged}"
VerticalAlignment="Center"/>