Как очистить WPF PasswordBox, связанный с ViewModel через Поведение?

3

Я пишу приложение WPF MVVM Prism 6.2. В окне входа в систему (это PrismUserControl) у меня есть привязка PaswordBox (через поведение) к свойству "Пароль" в модели вида. PasswordBox должен быть пустым каждый раз, когда вызывается окно входа во время работы приложения. (Например, после закрытия пользователем текущего сеанса он или она должен видеть только пустое окно Shell и входа в систему над командной оболочкой.) Моя проблема заключается в том, что вышеупомянутый PasswordBox отображается пустым только в первый раз после загрузки приложения. Если PaswordBox отображается во второй или третий раз и т.д., То он не пуст. См. Рисунок ниже:

Изображение 174551

Как вы видите, пароль не пуст, но в этом случае он должен быть пустым. Ниже приведен фрагмент 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 был пустым каждый раз, когда во время работы приложения отображается окно входа в систему. Я попытался очистить программно свойство "Пароль" в модели представления, но это не помогает. Как мне это сделать? Пожалуйста помоги.

Теги:
wpf
mvvm
behavior

2 ответа

6

Вы можете подключить PropertyChangedCallback для Password свойства зависимости от вашего поведения, которое устанавливает Password свойство PasswordBox в пустую строку, если Password источник свойство модели представления устанавливается в 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);
            }
        }
    }
}

Затем вы можете очистить PasswordBox, просто установив для свойства источника Password значение null в вашей модели просмотра.

  • 0
    мм8, большое спасибо за вашу помощь. Теперь пароль сбрасывается каждый раз, когда отображается окно входа в систему.
  • 1
    Значит, все работает как положено? Пожалуйста, не забудьте принять ответ и проголосовать за него: meta.stackexchange.com/questions/5234/…
Показать ещё 2 комментария
0

Более простой подход. Это очищает текстовое поле passwordBox каждый раз, когда экран (сетка, в которой находится элемент PasswordBox) закрывается.

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

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

В коде позади:

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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню