How can I get password from passwordbox?
1. I dont want to violate MVVM pattern (at least not to much)
2. I cant use code-behind because I use data templates to create my views. I have to use them because I am making window that contains pages. So I store page viewmodels in my window viewmodel and attach them to ContentControl when I need to navigate to any of them. I have to do this as I share my model between them.
3. I want some level of security as well, so I dont want to "hack" password box in order to bind password property.
Is this impossible?
I dont use any MVVM-frameworks. And I know there are lots of questions about passwordbox and MVVM but none of them deal with data templates. Even more, I have 2 passwordboxes in my view (second for "confirm password") and I cant just pass PasswordBox as CommandParameter (because I have 2 of them and passing element containing them is absolutely barbaric)
Serious, there is no real mvvm solution for the passwordbox, which maintains the security like without mvvm.
In my opinion the best / least bad way of working with the password box in an mvvm-built application is to give the whole passwordbox control to your viewmodel via a commandparameter (like in a login/register button) and hand it over to your internal classes/services until you really need to get the password out for a webservice or something like that.
It definitely breaks the mvvm-pattern because your viewmodel knowns about a control, but it's the most secure solution, which can be easily implement in most mvvm-built applications.
EDIT: You can easily pass two or more passwordboxes via the command parameter if you need them. (Like for a register dialog, where users have to type their password two times and they have to match.) This can be done via MultiBinding of the Commandparameter:
<Button.CommandParameter>
<MultiBinding Converter="{local:ItemsToListConverter}">
<Binding ElementName="nameOfPasswordBox1" />
<Binding ElementName="nameOfPasswordBox2" />
</MultiBinding>
</Button.CommandParameter>
The Converter just returns all values as a new List:
[MarkupExtensionReturnType(typeof(ItemsToListConverter))]
public class ItemsToListConverter : MarkupExtension, IMultiValueConverter
{
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (values == null) return values;
return values.ToList();
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
And in your ViewModel you have your normal ICommand which takes an object as parameter. You can there cast that object to a list of PasswordBoxes. (In my example it's a RegisterCommand with a Method 'Register'):
private void Register(object obj)
{
IEnumerable<PasswordBox> passwordBoxes = (obj as IList).Cast<PasswordBox>();
//Do whatever with your PasswordBoxes =)
}