Я искал решение MVVM «Установка и получение строки пароля из PasswordBox».
Решение, которое я нашел, используя класс Behavior из System.Windows.Interactivity.
Вот код:
Вид:
<PasswordBox Name="pass" >
<i:Interaction.Behaviors>
<vm:PasswordBehavior Password="{Binding Password, Mode=TwoWay}" />
</i:Interaction.Behaviors>
</PasswordBox>
А вот ViewModel:
public class PasswordBehavior : Behavior<PasswordBox>
{
public static readonly DependencyProperty PasswordProperty =
DependencyProperty.Register("Password", typeof(string), typeof(PasswordBehavior), new PropertyMetadata(default(string)));
private bool _skipUpdate;
public string Password
{
get { return (string)GetValue(PasswordProperty); }
set { SetValue(PasswordProperty, value); }
}
protected override void OnAttached()
{
AssociatedObject.PasswordChanged += PasswordBox_PasswordChanged;
}
protected override void OnDetaching()
{
AssociatedObject.PasswordChanged -= PasswordBox_PasswordChanged;
}
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
if (e.Property == PasswordProperty)
{
if (!_skipUpdate)
{
_skipUpdate = true;
AssociatedObject.Password = e.NewValue as string;
_skipUpdate = false;
}
}
}
private void PasswordBox_PasswordChanged(object sender, RoutedEventArgs e)
{
_skipUpdate = true;
Password = AssociatedObject.Password;
_skipUpdate = false;
}
}
И это работает! Я вижу пароль в ВМ, но есть еще одна проблема: теперь у меня в ВМ два отдельных класса: один из кода выше и второй класс MainLoginFormViewModel: BaseViewModel, который содержит все другие свойства, такие как имя пользователя, и команды для проверки соединения и т. Д. .
namespace MyApp.ViewModels
{
public class PasswordBehavior : Behavior<PasswordBox>
{
...
}
class MainLoginFormViewModel : BaseViewModel
{
public MainWindowViewModel()
{
sStatus = "Hello";
GetLoginData();
}
private string _sStatus;
public string sStatus
{
get { return _sStatus; }
set { _sStatus = value; NotifyPropertyChanged("sStatus"); }
}
private string _sServer;
public string sServer
{
get { return _sServer; }
set { _sServer = value; NotifyPropertyChanged("sServer"); }
}
private string _sName;
public string sName
{
get { return _sName; }
set { _sName = value; NotifyPropertyChanged("sName"); }
}
//...
}
}
Я не могу смешать эти два предложения, потому что одно из них вложено в BaseViewModel, для которого необходимо реализовать INotifyPropertyChanged, а второе - в Behavior, что мне тоже нужно.
Как я могу получить значение пароля из класса PasswordBehavior в Main MainLoginFormViewModel с логикой авторизации? Казалось, я что-то упустил, но не могу понять, что ....
P.S. Я знаю, что есть другой способ решить проблему с PasswordBox в MVVM, например передать весь элемент управления passwordbox в viewmodel, но таким образом я не могу установить пароль от VM (заставить приложение «запомнить» последний пароль при запуске приложения)