眾所周知,WPF 的
PasswordBox控件因?yàn)榘踩?,默認(rèn)不支持MVVM的雙向數(shù)據(jù)綁定,那么我們?cè)贛VVM開(kāi)發(fā)的過(guò)程中如何解決這個(gè)問(wèn)題呢?
添加附加屬性
新建PasswordBoxHelper.cs文件,添加如下的附加屬性:
using System.Windows;
using System.Windows.Controls;
namespace PasswordBoxControl.Helpers
{
public class PasswordBoxHelper
{
public static readonly DependencyProperty PasswordProperty = DependencyProperty.RegisterAttached(
"Password", typeof(string), typeof(PasswordBoxHelper), new PropertyMetadata(string.Empty,OnPasswordPropertyChanged));
private static void OnPasswordPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
PasswordBox passwordBox=d as PasswordBox;
passwordBox.PasswordChanged -= PasswordChanged;
if (!GetIsUpdating(passwordBox))
{
/*從Password往控件方向更新綁定值*/
passwordBox.Password = e.NewValue.ToString();
}
passwordBox.PasswordChanged += PasswordChanged;
}
public static void SetPassword(DependencyObject element, string value)
{
element.SetValue(PasswordProperty, value);
}
public static string GetPassword(DependencyObject element)
{
return (string) element.GetValue(PasswordProperty);
}
public static readonly DependencyProperty AttachProperty = DependencyProperty.RegisterAttached(
"Attach", typeof(bool), typeof(PasswordBoxHelper), new PropertyMetadata(false,Attach));
private static void Attach(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (!(d is PasswordBox passwordBox))
{
return;
}
if ((bool)e.OldValue)
{
passwordBox.PasswordChanged -= PasswordChanged;
}
if ((bool)e.NewValue)
{
/*當(dāng)控件的值發(fā)生變化的時(shí)候,更新Password的值*/
passwordBox.PasswordChanged += PasswordChanged;
}
}
private static void PasswordChanged(object sender, RoutedEventArgs e)
{
PasswordBox passwordBox=sender as PasswordBox;
/*IsUpdating的作用類(lèi)似一把互斥鎖,因涉及到雙向綁定更新*/
SetIsUpdating(passwordBox,true);
SetPassword(passwordBox,passwordBox.Password);
SetIsUpdating(passwordBox,false);
}
public static void SetAttach(DependencyObject element, bool value)
{
element.SetValue(AttachProperty, value);
}
public static bool GetAttach(DependencyObject element)
{
return (bool) element.GetValue(AttachProperty);
}
public static readonly DependencyProperty IsUpdatingProperty = DependencyProperty.RegisterAttached(
"IsUpdating", typeof(bool), typeof(PasswordBoxHelper), new PropertyMetadata(default(bool)));
public static void SetIsUpdating(DependencyObject element, bool value)
{
element.SetValue(IsUpdatingProperty, value);
}
public static bool GetIsUpdating(DependencyObject element)
{
return (bool) element.GetValue(IsUpdatingProperty);
}
}
}
如何使用呢?
在需要用的PasswordBox中添加上面寫(xiě)的附加屬性Password即可:
<PasswordBox Helper:PasswordBoxHelper.Attach="True"
Helper:PasswordBoxHelper.Password="{Binding Password,Mode=TwoWay}"/>