如何通过Behavior清除绑定到ViewModel的WPF PasswordBox?

时间:2017-02-18 12:51:26

标签: c# wpf mvvm behavior

我编写WPF MVVM Prism 6.2应用程序。在登录窗口(即PrismUserControl)的视图中,我在视图模型中将PaswordBox绑定(通过行为)到“密码”属性。 每次在应用程序运行时调用登录窗口时,PasswordBox必须为空。 (例如,在用户关闭当前会话后,他或她必须只看到Shell上方的空Shell和登录窗口。)我的问题是上面的PasswordBox仅在应用程序加载后第一次显示为空。如果在第二次或第三次e.t.c中显示PaswordBox,则它不为空。请参见下图:

enter image description here

如您所见,密码不为空,但在这种情况下必须为空。以下是来自登录窗口标记的XAML片段,其中PaswordBox为:

. . . . . . . . . . . . . .
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
. . . . . . . . . . . . . .
<PasswordBox Grid.Row="1" Grid.Column="1" Height="30" Margin="0 10 5 0" AutomationProperties.AutomationId="UserPasswordBox">
        <i:Interaction.Behaviors>
            <behavior:PasswordBoxBindingBehavior Password="{Binding Password}"/>
        </i:Interaction.Behaviors>
</PasswordBox>
. . . . . . . . . . . . . . . .

以下是XAML中涉及的行为类,如上所示:

public class PasswordBoxBindingBehavior : Behavior<PasswordBox>
{
    protected override void OnAttached()
    {
        AssociatedObject.PasswordChanged += OnPasswordBoxValueChanged;
    }

    public SecureString Password
    {
        get { return (SecureString)GetValue(PasswordProperty); }
        set { SetValue(PasswordProperty, value); }
    }

    public static readonly DependencyProperty PasswordProperty =
        DependencyProperty.Register("Password", typeof(SecureString), typeof(PasswordBoxBindingBehavior), new PropertyMetadata(null));

    private void OnPasswordBoxValueChanged(object sender, RoutedEventArgs e)
    {
        var binding = BindingOperations.GetBindingExpression(this, PasswordProperty);
        if (binding != null)
        {
            PropertyInfo property = binding.DataItem.GetType().GetProperty(binding.ParentBinding.Path.Path);
            if (property != null)
                property.SetValue(binding.DataItem, AssociatedObject.SecurePassword, null);
        }
    }
}

以下是视图模型中的“密码”属性。 PasswordBox通过PasswordBoxBindingBehavior:

绑定到此属性
public SecureString Password
{
    get { return this._password; }
    set { this.SetProperty(ref this._password, value); }
}

每次在应用程序工作期间显示登录窗口时,我都要求PasswordBox为空。我试图在视图模型中以编程方式清除“密码”属性,但它没有帮助。我该怎么做?请帮忙。

2 个答案:

答案 0 :(得分:7)

您可以为行为的PropertyChangedCallback依赖项属性挂钩Password,将Password的{​​{1}}属性设置为空字符串{{1视图模型的source属性设置为PasswordBox

Password

然后,您只需在视图模型中将null source属性设置为null即可清除public class PasswordBoxBindingBehavior : Behavior<PasswordBox> { protected override void OnAttached() { AssociatedObject.PasswordChanged += OnPasswordBoxValueChanged; } public SecureString Password { get { return (SecureString)GetValue(PasswordProperty); } set { SetValue(PasswordProperty, value); } } public static readonly DependencyProperty PasswordProperty = DependencyProperty.Register("Password", typeof(SecureString), typeof(PasswordBoxBindingBehavior), new PropertyMetadata(OnSourcePropertyChanged)); private static void OnSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { if(e.NewValue == null) { PasswordBoxBindingBehavior behavior = d as PasswordBoxBindingBehavior; behavior.AssociatedObject.PasswordChanged -= OnPasswordBoxValueChanged; behavior.AssociatedObject.Password = string.Empty; behavior.AssociatedObject.PasswordChanged += OnPasswordBoxValueChanged; } } private static void OnPasswordBoxValueChanged(object sender, RoutedEventArgs e) { PasswordBox passwordBox = sender as PasswordBox; var behavior = Interaction.GetBehaviors(passwordBox).OfType<PasswordBoxBindingBehavior>().FirstOrDefault(); if(behavior != null) { var binding = BindingOperations.GetBindingExpression(behavior, PasswordProperty); if (binding != null) { PropertyInfo property = binding.DataItem.GetType().GetProperty(binding.ParentBinding.Path.Path); if (property != null) property.SetValue(binding.DataItem, passwordBox.SecurePassword, null); } } } }

答案 1 :(得分:0)

更简单的方法。每次关闭屏幕(PasswordBox元素所在的网格)时,都会清除passwordBox文本框。

<Grid  Grid.LostFocus="event_method" ...

<PasswordBox x:Name="passwordBox" ...

在后面的代码中:

public event_method()
{
    passwordBox.Clear();
}