【问题标题】:WPF MVVM PasswordBox BindingWPF MVVM 密码框绑定
【发布时间】:2016-04-21 16:10:38
【问题描述】:

我目前在 WPF 应用程序中的 PasswordBox 上使用以下附加行为。我可以使用 UI 设置密码,我加密这个值并存储在数据库中。 加载视图模型并设置绑定到 PasswordBox 的 SecureString 属性时,密码字段显示为空。 (即使密码加载成功)。

在从 ViewModel 设置值时,为了让 PasswordBox 显示为已填充,我需要进行哪些更改?

我已添加在 XAML 和 ViewModel 中使用的代码。 LoadPassword() 方法返回一个 SecureString。

行为

/// <summary>
/// Provides additional properties to use against PasswordBox controls.
/// </summary>
/// <remarks>
/// Sometimes controls have properties that don't support binding. PasswordBox is one of these, where Microsoft's implementation does not support binding against the entered
/// password (for 'security purposes').
/// 
/// This class provides an 'attached property' which allows us to bridge the gap between the view and view model.
/// </remarks>
public static class Password
{
    #region Dependency properties

    /// <summary>
    /// SecurePassword property.
    /// </summary>
    public static readonly DependencyProperty SecurePasswordProperty = DependencyProperty.RegisterAttached("SecurePassword", typeof(SecureString), typeof(Password), new FrameworkPropertyMetadata(OnSecurePasswordChanged));

    /// <summary>
    /// HasSecurePassword property.
    /// </summary>
    private static readonly DependencyProperty HasSecurePasswordProperty = DependencyProperty.RegisterAttached("HasSecurePassword", typeof(bool), typeof(Password));

    #endregion

    #region Methods

    /// <summary>
    /// Sets the value of the SecurePassword property.
    /// </summary>
    /// <param name="dependencyObject">The object to set the property for.</param>
    /// <param name="value">The value to set.</param>
    public static void SetSecurePassword(DependencyObject dependencyObject, SecureString value)
    {
        if (dependencyObject == null)
            throw new ArgumentNullException(nameof(dependencyObject));

        dependencyObject.SetValue(Password.SecurePasswordProperty, value);
    }

    /// <summary>
    /// Gets the value of the SecurePassword property.
    /// </summary>
    /// <param name="dependencyObject">The object to get the property for.</param>
    /// <returns>The current value.</returns>
    public static SecureString GetSecurePassword(DependencyObject dependencyObject)
    {
        if (dependencyObject == null)
            throw new ArgumentNullException(nameof(dependencyObject));

        return (SecureString)dependencyObject.GetValue(Password.SecurePasswordProperty);
    }

    #endregion

    /// <summary>
    /// Handles the SecurePassword value changing.
    /// </summary>
    private static void OnSecurePasswordChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e)
    {
        PasswordBox password = dependencyObject as PasswordBox;

        bool? isRegistered = (bool?)password?.GetValue(Password.HasSecurePasswordProperty);
        if (isRegistered == false)
        {
            // register with the PasswordBox's PasswordChanged event so that we can keep updated with the latest value entered by the user
            password.PasswordChanged += (s, ee) => SetSecurePassword(password, password.SecurePassword);
            password.SetValue(Password.HasSecurePasswordProperty, true);
        }
    }
}

XAML

<PasswordBox Grid.Column="1" Grid.Row="2" behaviours:Password.SecurePassword="{Binding Path=Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="2"/>

视图模型

public SecureString Password
{
    get { return this._password; }
    set { base.SetProperty(ref _password, value); }
}

public SettingsViewModel()
{
    this.Password = LoadPassword();
}

【问题讨论】:

  • 能否包含该属性的 PasswordBox XAML 和 ViewModel 代码?
  • @GlenThomas 我添加了更多代码示例,它们显示了更大的图景。我本来应该把它们包括在内的,对此感到抱歉。
  • 不存储密码,甚至不加密!永远不要在 UI 中显示密码。存储密码的哈希值。

标签: c# wpf mvvm


【解决方案1】:

您根本无法设置SecurePassword。它是一个只读属性。如果要填写 PasswordBox,则必须设置 Unsecure String Password 属性。

【讨论】:

    猜你喜欢
    • 2017-04-20
    • 1970-01-01
    • 2015-09-15
    • 2015-10-16
    • 1970-01-01
    • 2021-10-11
    • 2015-07-11
    • 2015-04-27
    • 1970-01-01
    相关资源
    最近更新 更多