WPF 解决PasswordBox 属性Password无法绑定到后台的问题

发布时间 2023-12-12 21:31:49作者: 哈哈一笑很倾城

在 WPF 中,你可以使用密码框的 Password 属性来绑定到后台,但是由于安全性考虑,WPF 的密码框不直接支持双向绑定。然而,你仍然可以通过其他方式实现将密码框的内容绑定到后台。

一种常见的方法是创建一个附加属性(Attached Property)来实现密码框的双向绑定。以下是一个简单的示例代码:

csharpCopy Code
public static class PasswordBoxHelper
{
    public static readonly DependencyProperty BoundPassword =
        DependencyProperty.RegisterAttached("BoundPassword", typeof(string), typeof(PasswordBoxHelper), new PropertyMetadata(string.Empty, OnBoundPasswordChanged));

    public static readonly DependencyProperty BindPassword = DependencyProperty.RegisterAttached(
        "BindPassword", typeof(bool), typeof(PasswordBoxHelper), new PropertyMetadata(false, OnBindPasswordChanged));

    private static bool _isUpdating;

    public static void SetBindPassword(DependencyObject dp, bool value)
    {
        dp.SetValue(BindPassword, value);
    }

    public static bool GetBindPassword(DependencyObject dp)
    {
        return (bool)dp.GetValue(BindPassword);
    }

    public static string GetBoundPassword(DependencyObject dp)
    {
        return (string)dp.GetValue(BoundPassword);
    }

    public static void SetBoundPassword(DependencyObject dp, string value)
    {
        dp.SetValue(BoundPassword, value);
    }

    private static void OnBoundPasswordChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var passwordBox = d as PasswordBox;

        if (passwordBox == null)
        {
            return;
        }

        passwordBox.PasswordChanged -= PasswordChanged;

        if (!_isUpdating)
        {
            passwordBox.Password = (string)e.NewValue;
        }

        passwordBox.PasswordChanged += PasswordChanged;
    }

    private static void OnBindPasswordChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e)
    {
        var passwordBox = dp as PasswordBox;

        if (passwordBox == null)
        {
            return;
        }

        if ((bool)e.OldValue)
        {
            passwordBox.PasswordChanged -= PasswordChanged;
        }

        if ((bool)e.NewValue)
        {
            passwordBox.PasswordChanged += PasswordChanged;
        }
    }

    private static void PasswordChanged(object sender, RoutedEventArgs e)
    {
        var passwordBox = (PasswordBox)sender;
        _isUpdating = true;
        SetBoundPassword(passwordBox, passwordBox.Password);
        _isUpdating = false;
    }
}

在 XAML 中,你可以这样使用这个附加属性:

xmlCopy Code
<PasswordBox local:PasswordBoxHelper.BindPassword="True" 
             local:PasswordBoxHelper.BoundPassword="{Binding YourPasswordProperty, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

在这个示例中,YourPasswordProperty 是你 ViewModel 中表示密码的属性,它使用了双向绑定,允许将密码框中的内容绑定到后台。

通过使用附加属性,你可以实现密码框与后台属性的双向绑定,确保安全性的同时满足 MVVM 设计模式的要求。