7

I have a MVVM run treeview. On the top level is an Account object that contains credentials. I have a PasswordBox that can be used to change the account password with a Save button right behind it. The code is as follows and is part of the Account level template:

PasswordBox Width="100" x:Name="pbPassword"/>

Button x:Name="btnSave" Command="{Binding ClickCommand}" CommandParameter="{Binding ElementName=pbPassword, Path=Password}" Height="20" Width="50">Save

I put something into the PasswordBox and then click Save. The ClickCommand fires, but the parameter is always string.Empty. What am I missing?

light
  • 816
  • 5
  • 16
  • 1
    This question has been answered here: http://stackoverflow.com/questions/1483892/wpf-binding-to-the-passwordbox-in-mvvm-working-solution – light May 03 '11 at 01:58

2 Answers2

11

For security reasons, WPF doesn't provide a dependency property for the Password property of PasswordBox (reference 1, 2), so your command parameter binding doesn't work.

You could bind the command argument to PasswordBox, then access the appropriate property from within your command implementation:

<Button Command="{Binding ClickCommand}" CommandParameter="{Binding ElementName=pbPassword}">

// command implementation
public void Execute(object parameter)
{
    var passwordBox = (PasswordBox)parameter;
    var value = passwordBox.Password;
}

You may want to consider other options that do not involve keeping the password in memory as plain text.

Hope this helps,
Ben

Community
  • 1
  • 1
Ben Gribaudo
  • 5,057
  • 1
  • 40
  • 75
  • Thanks, that helps to know I can bind directly to the PasswordBox itself. This allows me to persist this data directly from within my command encrypted in the database then dispose of the Password immediately without actually assigning it to a variable. – light May 03 '11 at 02:37
-2

--PLEASE STOP MARKING ME DOWN ON THIS, See comment below, this does not work, but left in so no-one else makes the same mistake--

Sorry old Q, but found an improvement on that

<Button Content="Log On" 
  Command="{Binding LogOnCommand}" 
  CommandParameter="{Binding ElementName=PasswordControl, Path=SecurePassword}" />

that way your command need only know about a SecureString object

public override void Execute(object parameter)
{
    _viewModel.LogOnAsync((SecureString)parameter);
}

keeping knowledge of the ui from the command

Anthony Johnston
  • 9,405
  • 4
  • 46
  • 57