Home .NET Accessing PasswordBox in MVVM environment

Accessing PasswordBox in MVVM environment

by admin

Having first read Josh Smith’s famous article WPF Apps With The Model-View-ViewModel Design Pattern I was very inspired by the MVVM philosophy and decided to write all future projects using it exclusively. As I "implemented" MVVM I encountered some difficulties and shortcomings (in my subjective opinion). In one project, I needed a UserControl which would allow me to authorize a web service. When I tried to bind the ViewModel property to the PasswordBox control, I got the following error :
A ‘Binding’ cannot be set on the ‘Password’ property of type ‘PasswordBox’. A ‘Binding’ can only be set on a DependencyProperty of a DependencyObject
The reason the Password property is not made a DependencyProperty is due to security reasons. If you could bind the property to PasswordBox, then it would be stored in memory in an open form, and that’s not a good idea from Microsoft’s point of view. Therefore, the password in PasswordBox is stored in encrypted form and is decrypted when the Password property is called.
I have found several solutions to this problem. There are ways that retain the principles of MVVM, but create the problem described above. If the requirements do not provide this kind of security, you can go against the system using the Attached Properties to bind the ViewModel property. I will describe another way, which probably breaks MVVM principles a bit but keeps the password storage security.
Create a simple control :

<Label Content="Login:" HorizontalAlignment="Right"/> <TextBox Grid.Column="1" Margin="3" Text="{Binding UserName, Mode=TwoWay}"/> <Label Grid.Row="1" Content="Password:" HorizontalAlignment="Right"/> <PasswordBox Grid.Row="1" Grid.Column="1" Margin="3" Name="pwdBox"/> <Button Grid.Row="2" Grid.ColumnSpan="2" Width="70" Height="25"HorizontalAlignment="Right" Content="Login"Command="{Binding LoginCommand}"/>

To get the password, we need the interface :

public interface IPasswordSupplier{string GetPassword();}

Inherit a controller from this interface and return the password value to the function :

public partial class LoginControl : UserControl, IPasswordSupplier{public LoginControl(){InitializeComponent();}public string GetPassword(){return pwdBox.Password;}}

The unpleasant thing about this method is that LoginControl has to be created in the code, because we need to get the IPasswordSupplier. Using the IoC container we register an instance of the cotrol in App.xaml.cs:

protected override void OnStartup(StartupEventArgs e){base.OnStartup(e);IUnityContainer container = new UnityContainer();LoginControl loginControl = new LoginControl();container.RegisterInstance<IPasswordSupplier> (loginControl);LoginViewModel loginViewModel = new LoginViewModel(container);loginControl.DataContext = loginViewModel;MainWindow mainWindow = new MainWindow(loginControl);MainWindowViewModel windowViewModel = new MainWindowViewModel(loginViewModel);mainWindow.DataContext = windowViewModel;mainWindow.Show();}

Now we can access the PasswordBox property in the ViewModel of the control:

public string Password{get{IPasswordSupplier passwordSupplier = container.Resolve<IPasswordSupplier> ();return passwordSupplier.GetPassword();}}

So, the Password property of our ViewModel doesn’t store the password value, but gets it each time it’s accessed from PasswordBox, which in turn decrypts it for us. Perhaps this violates MVVM, because now our ViewModel is indirectly connected to the View through this interface, but still this way seems the most appropriate to me to solve the problem.

You may also like