Unable to data-bind to a PasswordBox
-
Friday, October 28, 2005 1:30 AMWhen I attempt to bind to the Password property of the PasswordBox (binded to a property on an object that returns a string), I get the following error:
Object of type 'System.Windows.Data.Binding' cannot be converted to type 'System.String'.
Is string the wrong type....I tried char[] with the same result.
Answers
-
Wednesday, November 09, 2005 5:43 PM
PasswordBox.Password doesn't have a corresponding DependencyProperty, so you can't data-bind to it.
Exposing a DependencyProperty would require us to store the PasswordBox content plain text in memory in the property system -- which is a security concern. The PasswordBox encrypts its content and only generates plain text on demand when a caller references the Password CLR property. -
Monday, June 23, 2008 4:58 PMModerator
As Ben mentioned, Databinding passwords is not a good design for security reasons and should be avoided.- Marked As Answer by LesterLobo - MSFTModerator Sunday, June 29, 2008 4:33 PM
-
Sunday, June 29, 2008 4:32 PMModerator
exposing a securestring password is something that we are looking at for the current release.- Marked As Answer by LesterLobo - MSFTModerator Sunday, June 29, 2008 4:33 PM
All Replies
-
Friday, October 28, 2005 2:26 AMModeratorYou can't bind the property beause it is not a DependencyProperty. It is probably not a DP because Microsoft doesn't see any point in it being one and I'm inclined to share that perspective. In what scenario would you ever want to databind to a password box?
HTH,
Drew -
Friday, October 28, 2005 5:15 AMI would like to bind to the Password box for the reason why you would want to data-bind anything...that is to enable the UI (XAML) to be less coupled to the application logic. Without binding, I would have to know the name associated with the password box and then from code get a reference to the password box and directly access its Password property. With binding, I simply know that there some data object bound to the page (or window, dialog, etc) and then get the password value from that object.
-
Wednesday, November 09, 2005 5:43 PM
PasswordBox.Password doesn't have a corresponding DependencyProperty, so you can't data-bind to it.
Exposing a DependencyProperty would require us to store the PasswordBox content plain text in memory in the property system -- which is a security concern. The PasswordBox encrypts its content and only generates plain text on demand when a caller references the Password CLR property. -
Wednesday, December 06, 2006 5:04 PM
Hi,
I want to use the Password of a PasswordBox as CommandParameter of a Button.
Since the Password can't be dinding, how to do so?
-
Monday, June 23, 2008 9:51 AM
I've created a method to allow the Password on PasswordBox to be databound (using attached properties).
You can get the code here: http://blog.functionalfun.net/2008/06/wpf-passwordbox-and-data-binding.html -
Monday, June 23, 2008 4:58 PMModerator
As Ben mentioned, Databinding passwords is not a good design for security reasons and should be avoided.- Marked As Answer by LesterLobo - MSFTModerator Sunday, June 29, 2008 4:33 PM
-
Tuesday, June 24, 2008 9:27 AMLester,
I agree that databinding passwords sometimes isn't a good idea, but I've posted my reasons why I don't think its always a problem in this post over here: http://forums.msdn.microsoft.com/en-US/wpf/thread/d5d9c146-3379-4a1e-8671-d37367ad4906.
Could you explain further why you think it is always a bad idea? Also, is there a reason why you haven't exposed a SecureString-type property on PasswordBox, and why such a SecureString property couldn't be a dependency property?
I'd really like to understand this.
Thanks,
Sam -
Sunday, June 29, 2008 4:32 PMModerator
exposing a securestring password is something that we are looking at for the current release.- Marked As Answer by LesterLobo - MSFTModerator Sunday, June 29, 2008 4:33 PM
-
Friday, July 03, 2009 11:04 PM
So the reason we can't bind password is security?!
What about Adding a dependency property at the view and we will do binding from the View Model to the DP.
the DP will be filled with the password from the password box only when we need it (when we do login or any other command that we wanted to do) and we will clear the property right after that the View Model get the password and before any other function.
That way we keep the view model and the view less coupled and we keep the security advantage of the Password Box. -
Friday, March 05, 2010 5:28 PMSo is the securestring dependency property going to be available for .NET v4? Thanks
-
Friday, March 12, 2010 4:31 AM
I've just been working on some code that involves multiple password boxes in one view, and I didn't want to end up wiring up lots of event handlers to cater for keeping the view and viewmodel in sync.
The XAML looks like:<Window x:Class="WPFTagTest.Window1" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="Auto" Width="Auto" SizeToContent="WidthAndHeight"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto"/> <RowDefinition Height="Auto"/> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"/> <ColumnDefinition Width="200"/> <ColumnDefinition Width="200"/> </Grid.ColumnDefinitions> <Label Grid.Row="0" Grid.Column="0" Margin="3,3,3,3" >Password 1</Label> <PasswordBox Grid.Row="0" Grid.Column="1" Margin="3,3,3,3" Tag="{Binding Password1Property}" Loaded="PasswordBox_Loaded" PasswordChanged="PasswordBox_PasswordChanged" /> <Label Grid.Row="1" Grid.Column="0" Margin="3,3,3,3">Password 2</Label> <PasswordBox Grid.Row="1" Grid.Column="1" Margin="3,3,3,3" Tag="{Binding Password2Property}" Loaded="PasswordBox_Loaded" PasswordChanged="PasswordBox_PasswordChanged" /> <TextBlock Grid.Row="0" Grid.Column="2" VerticalAlignment="Center" Text="{Binding Path=Password1}" /> <TextBlock Grid.Row="1" Grid.Column="2" VerticalAlignment="Center" Text="{Binding Path=Password2}" /> </Grid> </Window>
and the code behind it is
using System; using System.Windows; using System.Windows.Controls; using System.ComponentModel; namespace WPFTagTest { /// <summary> /// Interaction logic for Window1.xaml /// </summary> public partial class Window1 : Window { private MyViewModel m_viewModel = new MyViewModel() { Password1 = "test1", Password2 = "test2" }; public Window1() { this.DataContext = m_viewModel; InitializeComponent(); } private void PasswordBox_PasswordChanged(object sender, RoutedEventArgs e) { var passwordBox = sender as PasswordBox; if ((passwordBox != null) && (passwordBox.Tag != null)) { var property = passwordBox.Tag as PassableProperty<string>; if (property != null) property.Value = passwordBox.Password; } } private void PasswordBox_Loaded(object sender, RoutedEventArgs e) { var passwordBox = sender as PasswordBox; if ((passwordBox != null) && (passwordBox.Tag != null)) { var property = passwordBox.Tag as PassableProperty<string>; if (property != null) passwordBox.Password = property.Value; } } } // --------------------------------------------------------- public class PassableProperty<T> { private readonly Func<T> m_getter; private readonly Action<T> m_setter; public PassableProperty(Func<T> getter, Action<T> setter) { m_getter = getter; m_setter = setter; } public T Value { get { return m_getter(); } set { m_setter(value); } } } // --------------------------------------------------------- public class MyViewModel : INotifyPropertyChanged { private string m_password1; private string m_password2; public MyViewModel() { m_password1Property = new PassableProperty<string>( () => Password1, (val) => { Password1 = val; } ); m_password2Property = new PassableProperty<string>( () => Password2, (val) => { Password2 = val; } ); } public event PropertyChangedEventHandler PropertyChanged; private void RaisePropertyChanged(string sPropertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(sPropertyName)); } } public string Password1 { get { return m_password1; } set { m_password1 = value; RaisePropertyChanged("Password1"); } } private readonly PassableProperty<string> m_password1Property; public PassableProperty<string> Password1Property { get { return m_password1Property; } } public string Password2 { get { return m_password2; } set { m_password2 = value; RaisePropertyChanged("Password2"); } } private readonly PassableProperty<string> m_password2Property; public PassableProperty<string> Password2Property { get { return m_password2Property; } } } }
Whether it has saved me lines of code, I'm not sure. But it may pay off with more and more password boxes. -
Tuesday, April 06, 2010 6:17 PM
Since the Password property is not a dependency property there is no way you can bind to it, but you can bind to the PasswordBox or some element that contains the PasswordBox (just use CommandParameter="{Binding ElementName=NameOfElement}").
If you are using the Model-View-ViewModel pattern then the benefits/drawbacks of this solution are as follows:
+ One avoids the security risk associated with data-binding to a password.
+ A View can be completely independent of its ViewModel even if it contains a PasswordBox.
- A ViewModel that makes use of passwords will have to have some knowledge of its views.
+ Such a ViewModel can nevertheless be written in such a way that it can be unit-tested independently of its views. -
Monday, October 25, 2010 8:56 AM
I did the following:
Put a hidden Textbox (txtPassword) besides the Password (pwdPassword) and used code behind to update the source of binding:
private void pwdPassword_PasswordChanged(object sender, RoutedEventArgs e)
{
txtPassword.Text = MyUtils.CryptSha1(pwdPassword.Password);
txtPassword.GetBindingExpression(TextBox.TextProperty).UpdateSource();
}In the view I bind the txtPassword (hidden) to the password field of my ViewModel.
The MyUtils.CryptSha1 tries to avoid some security risks. Please advice if you think this is too weak.
It could be seen as a little break of MVVM too, but I prefer this way to have to write an speciallized class or a Password wrapper.
Greetings

