I searched for a MVVM solution of Setting and Retrieving Password String from PasswordBox. The solutuion I found using Behavior class from System.Windows.Interactivity. Here is the code: View:
<PasswordBox Name="pass" >
<i:Interaction.Behaviors>
<vm:PasswordBehavior Password="{Binding Password, Mode=TwoWay}" />
</i:Interaction.Behaviors>
</PasswordBox>
And here is the 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;
}
}
And it is works! I can see the password in VM, but here is another problem: now I have in VM two separated classes: one from code above and second Class MainLoginFormViewModel : BaseViewModel which contains all other properties, like user name, and commands for check connection, etc.
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"); }
}
//...
}
}
I cant mix those two clases, cause one of them is nested from BaseViewModel, which need to implement INotifyPropertyChanged, and second one nested from Behavior, which I need too.
How can I get Password value from class PasswordBehavior into Main MainLoginFormViewModel with authorization logic? It seemed like I missed smth, but I cant understand what....
P.S. I know that there is another way to solve problem with PasswordBox in MVVM, like pass the whole passwordbox control into viewmodel, but in that way I cant SET password from VM (make app "remember" last password on app launch)