WPF中实现PasswordBox的双向绑定
我们知道一个属性想要实现双向绑定,最基本的便是这个属性需要时依赖属性,但是微软工程师在设计的时候Password并不是依赖属性,那我们想要实现双向绑定该怎么去做呢?
最常用的便是改造PasswordBox,为它增加一个扩展属性,借助扩展属性实现Password的读写功能。
首先我们建一个PasswordBoxExtend的扩展类,输入快捷语句“propa”,然后按下“Tap”键,即可自动生成我们需要的所有函数。
之后我们改变一些主要内容
public static string GetPwd(DependencyObject obj)
{
return (string)obj.GetValue(PwdProperty);
}
public static void SetPwd(DependencyObject obj, string value)
{
obj.SetValue(PwdProperty, value);
}
public static readonly DependencyProperty PwdProperty =
DependencyProperty.RegisterAttached("Pwd", typeof(string), typeof(PasswordBoxExtend), new PropertyMetadata("", OnPwdChanged));
/// <summary>
/// 密码属性变化事件
/// </summary>
/// <param name="d"></param>
/// <param name="e"></param>
/// <exception cref="NotImplementedException"></exception>
private static void OnPwdChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
string newPwd = (string)e.NewValue;
if (d is PasswordBox passwordBox && passwordBox.Password != newPwd)
{
passwordBox.Password = newPwd;
}
}
这样就实现了当我们的附加属性发现变化的时候就会修改我们Password的值,但是我们Password的值改变后并不会通知我们附加属性,所以我们还需要建立一个PasswordBoxBehaviors行为事件类,让它继承Behavior,从而实现当Password改变时通知到我们的附加属性
/// <summary>
/// PasswordBox行为
/// 当Password变化时,触发自定义属性跟着变化
/// </summary>
public class PasswordBoxBehaviors : Behavior<PasswordBox>
{
/// <summary>
/// 附加行为
/// 注入事件
/// </summary>
protected override void OnAttached()
{
base.OnAttached();
this.AssociatedObject.PasswordChanged += OnPasswordChanged;
}
private void OnPasswordChanged(object sender, RoutedEventArgs e)
{
PasswordBox passwordBox = sender as PasswordBox;
string password = PasswordBoxExtend.GetPwd(passwordBox);
if (passwordBox!= null && password != passwordBox.Password)
{
PasswordBoxExtend.SetPwd(passwordBox, passwordBox.Password);
}
}
/// <summary>
/// 销毁行为
/// 移除事件
/// </summary>
protected override void OnDetaching()
{
base.OnDetaching();
this.AssociatedObject.PasswordChanged -= OnPasswordChanged;
}
}
然后我们在ViewModel中第一密码变量
/// <summary>
/// 密码
/// </summary>
private string _Pwd;
public string Pwd
{
get { return _Pwd; }
set { _Pwd = value; }
}
最后在前端绑定即可
<PasswordBox
Margin="0,10"
md:HintAssist.Hint="请输入密码"
pwdExtend:PasswordBoxExtend.Pwd="{Binding Pwd, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
DockPanel.Dock="Top">
<!--绑定行为-->
<i:Interaction.Behaviors>
<pwdExtend:PasswordBoxBehaviors />
</i:Interaction.Behaviors>
</PasswordBox>