5.4.1 Password控件的Password属性绑定问题
WPF的 PasswordBox 的 Password 属性是一个常规的 CLR 属性,而不是依赖属性(DependencyProperty),因此不能直接使用 WPF 的数据绑定机制
下图所示:
注意2个事项:
1.使用的是” DependencyProperty.RegisterAttached“
2.绑定时 双向绑定:{Binding loginModel.Password, Mode=TwoWay}
public class NotifyBase : INotifyPropertyChanged{public event PropertyChangedEventHandler PropertyChanged;public void DoNotify([CallerMemberName]string propName=""){PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propName));}} public class LoginModel : NotifyBase{private string _userName;public string UserName { get => _userName;set { _userName = value;this.DoNotify();} }private string _password;public string Password{get => _password;set{_password = value;this.DoNotify();}}} public class LoginViewModel{public LoginModel loginModel { get; set; }public CommandBase CloseWindowCommand { get; set; }public LoginViewModel(){this.loginModel = new LoginModel();this.loginModel.UserName = "abc";this.loginModel.Password = "123456";this.CloseWindowCommand = new CommandBase();this.CloseWindowCommand.DoExecute = new Action<object>(o =>{(o as Window).Close();});this.CloseWindowCommand.DoCanExecute=new Func<object, bool>(o=> { return true; });}}
public class PasswordHelper{// Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc...public static readonly DependencyProperty PasswordProperty =DependencyProperty.RegisterAttached("Password", typeof(string), typeof(PasswordHelper), new FrameworkPropertyMetadata("", OnPasswordChanged));public static string GetPassword(DependencyObject d){return d.GetValue(PasswordProperty).ToString();}public static void SetPassword(DependencyObject d,string value){d.SetValue(PasswordProperty, value);}/// <summary>/// 当设置此处PasswordProperty时--->更新到界面上。/// </summary>/// <param name="d"></param>/// <param name="e"></param>private static void OnPasswordChanged(DependencyObject d, DependencyPropertyChangedEventArgs e){PasswordBox password = d as PasswordBox;password.PasswordChanged -= Password_PasswordChanged;if (!_isUpdating)password.Password = e.NewValue.ToString();password.PasswordChanged += Password_PasswordChanged;}// Using a DependencyProperty as the backing store for MyProperty. This enables animation, styling, binding, etc...public static readonly DependencyProperty AttachProperty =DependencyProperty.RegisterAttached("Attach", typeof(bool), typeof(PasswordHelper), new PropertyMetadata(default(bool), OnAttached));public static bool GetAttach(DependencyObject d){return (bool)d.GetValue(AttachProperty);}public static void SetAttach(DependencyObject d, bool value){d.SetValue(AttachProperty, value);}static bool _isUpdating = false;/// <summary>/// 当设置Attach值时,触发此处的函数。/// </summary>/// <param name="d"></param>/// <param name="e"></param>private static void OnAttached(DependencyObject d, DependencyPropertyChangedEventArgs e){PasswordBox password = d as PasswordBox;password.PasswordChanged += Password_PasswordChanged;}/// <summary>/// UI上password的变化-->表用此函数/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private static void Password_PasswordChanged(object sender, RoutedEventArgs e){PasswordBox passwordbox = sender as PasswordBox;_isUpdating = true;SetPassword(passwordbox, passwordbox.Password);_isUpdating = false;}}
<PasswordBox Name="passwordbox" Width="200" Margin="12,0,0,0" VerticalAlignment="Center"common:PasswordHelper.Attach="True"common:PasswordHelper.Password="{Binding loginModel.Password, Mode=TwoWay}"/>