using System.Windows; using System.Windows.Controls; namespace FATrace.WPLApp.Utils { /// /// 允许将 PasswordBox 的 Password 与 ViewModel 绑定 /// 用法: /// /// public static class PasswordBoxAssistant { public static readonly DependencyProperty BoundPasswordProperty = DependencyProperty.RegisterAttached("BoundPassword", typeof(string), typeof(PasswordBoxAssistant), new PropertyMetadata(string.Empty, OnBoundPasswordChanged)); public static readonly DependencyProperty BindPasswordProperty = DependencyProperty.RegisterAttached("BindPassword", typeof(bool), typeof(PasswordBoxAssistant), new PropertyMetadata(false, OnBindPasswordChanged)); private static readonly DependencyProperty IsUpdatingProperty = DependencyProperty.RegisterAttached("IsUpdating", typeof(bool), typeof(PasswordBoxAssistant)); public static string GetBoundPassword(DependencyObject dp) => (string)dp.GetValue(BoundPasswordProperty); public static void SetBoundPassword(DependencyObject dp, string value) => dp.SetValue(BoundPasswordProperty, value); public static bool GetBindPassword(DependencyObject dp) => (bool)dp.GetValue(BindPasswordProperty); public static void SetBindPassword(DependencyObject dp, bool value) => dp.SetValue(BindPasswordProperty, value); private static bool GetIsUpdating(DependencyObject dp) => (bool)dp.GetValue(IsUpdatingProperty); private static void SetIsUpdating(DependencyObject dp, bool value) => dp.SetValue(IsUpdatingProperty, value); private static void OnBoundPasswordChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e) { if (dp is PasswordBox passwordBox) { passwordBox.PasswordChanged -= HandlePasswordChanged; if (!(bool)GetIsUpdating(passwordBox)) { passwordBox.Password = e.NewValue?.ToString() ?? string.Empty; } passwordBox.PasswordChanged += HandlePasswordChanged; } } private static void OnBindPasswordChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e) { if (dp is PasswordBox passwordBox) { bool wasBound = (bool)(e.OldValue ?? false); bool needBind = (bool)(e.NewValue ?? false); if (wasBound) { passwordBox.PasswordChanged -= HandlePasswordChanged; } if (needBind) { passwordBox.PasswordChanged += HandlePasswordChanged; } } } private static void HandlePasswordChanged(object sender, RoutedEventArgs e) { if (sender is PasswordBox passwordBox) { SetIsUpdating(passwordBox, true); SetBoundPassword(passwordBox, passwordBox.Password); SetIsUpdating(passwordBox, false); } } } }