2017-02-18 6 views
-1

Я пишу приложение WPF MVVM Prism 6.2. В окне входа в систему (это PrismUserControl) у меня есть привязка PaswordBox (через поведение) к свойству «Пароль» в модели вида. PasswordBox должен быть пустым каждый раз, когда вызывается окно входа во время работы приложения.(Например, после закрытия пользователем текущего сеанса он или она должен видеть только пустое окно оболочки и входа в систему над командной оболочкой.) Моя проблема заключается в том, что вышеупомянутый PasswordBox отображается пустым только в первый раз после загрузки приложения. Если PaswordBox отображается во второй или третий раз e.t.c, то он не пуст. Пожалуйста, смотрите изображение ниже:Как очистить WPF PasswordBox, связанный с ViewModel через поведение?

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

ответ

3

Вы можете подключить 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

mm8, большое спасибо за вашу помощь. Теперь Пароль очищается каждый раз, когда отображается окно входа в систему. – Prohor

+1

Значит, он работает так, как ожидалось? Не забудьте принять ответ и проголосовать за него: http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work – mm8

+0

Это очень умно, позволяет использовать PasswordBox в MVVM, спасибо за идею и код – ktingle

Смежные вопросы