I try to bind the SecurePassword
property of a PasswordBox
to my ViewModel
with a custom Behavior
. Sadly it doesn't work properly.
Basically I added a property to the Behavior
which contains the target property of my ViewModel
.
Any ideas why it doesn't work?
PS: I am currently on the way home without my laptop, I gonna update the question with my code in about 15 minutes. But would be nice if someone would post ideas or sth.
EDIT
As I promised, here is some code :)
The Behavior
first:
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using System.Windows.Interactivity;
using System.Security;
namespace Knerd.Behaviors {
public class PasswordChangedBehavior : Behavior<PasswordBox> {
protected override void OnAttached() {
AssociatedObject.PasswordChanged += AssociatedObject_PasswordChanged;
base.OnAttached();
}
private void AssociatedObject_PasswordChanged(object sender, RoutedEventArgs e) {
if (AssociatedObject.Password != null)
TargetPassword = AssociatedObject.SecurePassword;
}
protected override void OnDetaching() {
AssociatedObject.PasswordChanged -= AssociatedObject_PasswordChanged;
base.OnDetaching();
}
public SecureString TargetPassword {
get { return (SecureString)GetValue(TargetPasswordProperty); }
set { SetValue(TargetPasswordProperty, value); }
}
// Using a DependencyProperty as the backing store for TargetPassword. This enables animation, styling, binding, etc...
public static readonly DependencyProperty TargetPasswordProperty = DependencyProperty.Register("TargetPassword", typeof(SecureString), typeof(PasswordChangedBehavior), new PropertyMetadata(default(SecureString)));
}
}
The PasswordBox
:
<PasswordBox Grid.Column="1" Grid.Row="1" Margin="5" Width="300" MinWidth="200">
<i:Interaction.Behaviors>
<behaviors:PasswordChangedBehavior TargetPassword="{Binding Password}" />
</i:Interaction.Behaviors>
</PasswordBox>
And last, the part of my ViewModel
.
private SecureString password;
public SecureString Password {
get { return password; }
set {
if (password != value) {
password = value;
OnPropertyChanged("Password");
}
}
}
I hope anyone can help, atm I use the codebehind version but I rather wouldn't.
EDIT 2
What actually doesn't work is, that the TargetPassword
property doesn't update the property of my ViewModel
I think I found a kinda weird solution. Please improve if there is sth to improve :)
I just changed it like so:
The
Behavior
:The
ViewModel
didn't change at all, but here is myView
:That works just perfect, without exposing the plaintext password.
Create an attach property
And in your
XAML
You probably don't want to do this anyway but if you really want to go ahead.
I would suggest that when accessing the PasswordBox.Password CLR property you'd refrain from placing it in any variable or as a value for any property. Keeping your password in plain text on the client machine RAM is a security no-no.
SecurePassword
cannot be done with bindings.An alternative solution is to put the
PasswordBox
in yourViewModel
public class LoginViewModelYes, you are violating ViewModel best practices here, but