Reputation: 21
I am using a password box in WPF, when in edit mode the password box does not mask my password.
Here is an example of my code:
<PasswordBox Width="200" Password="{Binding Path=Password, ValidatesOnDataErrors=True, NotifyOnValidationError=True, Mode=TwoWay}" HorizontalAlignment="Left"/>
I have attempted including Passwordchar = '*'
Upvotes: 2
Views: 1326
Reputation: 427
For using a masked Password text box in WPF implement below methods:
Class constructor:
public Login_Form()
{
InitializeComponent();
Password_Text_Box.MaxLength = 7; // password 7 characters in length
AutoValidate = AutoValidate.Disable;
} // End of Login form initialization
Component validation:
private void Password_Text_Box_Validating(object sender, System.ComponentModel.CancelEventArgs e) {
bool cancel = false;
if (string.IsNullOrEmpty(Password_Text_Box.Text)) {
cancel = true;
ErrorProvider.SetError(Password_Text_Box, " MISSING PASSWORD "); }
e.Cancel = cancel; }
Logic behind a 'Key Press" action:
private void Password_Text_Box_KeyPress(object sender, KeyPressEventArgs e) {
if (e.KeyChar == (char)Keys.Enter) {
// if ENTER is hit , do something
e.Handled = true; //Handle the Keypress event (suppress the Beep) }
Password_Text_Box.PasswordChar = '*'; // masking input right away
e.Handled = !(char.IsDigit(e.KeyChar) || e.KeyChar == (char)Keys.Back);
e = null;} // not allowing certain types of input
You could also implement a pictogram that reveals and hides the entered sequence:
private void pictureBoxShowPassword_Click(object sender, EventArgs e) {
if (Password_Text_Box.PasswordChar == '*' & Password_Text_Box.Text != null) {
Password_Text_Box.PasswordChar = '\0'; } //revealing
else if (Password_Text_Box.PasswordChar == '\0'){
Password_Text_Box.PasswordChar = '*'; } } // hiding
What happens when you point and click the text box:
private void Password_Text_Box_MouseDown(object sender, MouseEventArgs e) {
if (Password_Text_Box.Text == "Password") {
Password_Text_Box.Text = ""; } }
All in all, you should be looking at something along these lines:
When a form and a text box loads, it displays a text - purpose of the component. When a user points a mouse and clicks on the component, the purpose text disappears. Upon entering a value, a masking symbol appears on the screen. Nearby by the Reveal button lets, you see the entered value before submission.
Upvotes: 0
Reputation: 6991
Both @JRB and @BorisErmako answers are probably valid, yet somehow heavyweight.
You don't need two-way data binding, do you? In most scenario you don't want to update the password field from code, do you? I guess you don't.
Then, just use an event to get notified. Inspired by Bind a WPF passwordbox I did:
<PasswordBox PasswordChanged="OnPasswordChanged" />
Assuming code-behind class has a pointer to the underlying model object as myViewModelObject
.
private void OnPasswordChanged(object sender, RoutedEventArgs e)
{
myViewModelObject.Password = ((PasswordBox)sender).Password;
}
This adds very few lines of code compared to the 89 to 108 extra lines of other answers. Extra bonus: for all practical purposes, this seems fully compatible with advanced framework like ReactiveUI.
Upvotes: 1
Reputation: 2136
you can't get password value direct in viewmodel due to security purpose, you have to create dependancy property.
below is code for password.
DP:
public static readonly DependencyProperty BoundPassword =
DependencyProperty.RegisterAttached("BoundPassword", typeof(string), typeof(PasswordBoxHelper), new PropertyMetadata(string.Empty, OnBoundPasswordChanged));
public static readonly DependencyProperty BindPassword = DependencyProperty.RegisterAttached(
"BindPassword", typeof(bool), typeof(PasswordBoxHelper), new PropertyMetadata(false, OnBindPasswordChanged));
private static readonly DependencyProperty UpdatingPassword =
DependencyProperty.RegisterAttached("UpdatingPassword", typeof(bool), typeof(PasswordBoxHelper), new PropertyMetadata(false));
private static void OnBoundPasswordChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var box = d as PasswordBox;
if(d == null || !GetBindPassword(d))
{
return;
}
box.PasswordChanged -= HandlePasswordChanged;
var newPassword = (string)e.NewValue;
if(!GetUpdatingPassword(box))
{
box.Password = newPassword;
}
box.PasswordChanged += HandlePasswordChanged;
}
private static void OnBindPasswordChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e)
{
var box = dp as PasswordBox;
if(box == null)
{
return;
}
bool wasBound = (bool)(e.OldValue);
bool needToBind = (bool)(e.NewValue);
if(wasBound)
{
box.PasswordChanged -= HandlePasswordChanged;
}
if(needToBind)
{
box.PasswordChanged += HandlePasswordChanged;
}
}
private static void HandlePasswordChanged(object sender, RoutedEventArgs e)
{
var box = sender as PasswordBox;
SetUpdatingPassword(box, true);
SetBoundPassword(box, box.Password);
SetUpdatingPassword(box, false);
}
public static void SetBindPassword(DependencyObject dp, bool value)
{
dp.SetValue(BindPassword, value);
}
public static bool GetBindPassword(DependencyObject dp)
{
return (bool)dp.GetValue(BindPassword);
}
public static string GetBoundPassword(DependencyObject dp)
{
return (string)dp.GetValue(BoundPassword);
}
public static void SetBoundPassword(DependencyObject dp, string value)
{
dp.SetValue(BoundPassword, value);
}
private static bool GetUpdatingPassword(DependencyObject dp)
{
return (bool)dp.GetValue(UpdatingPassword);
}
private static void SetUpdatingPassword(DependencyObject dp, bool value)
{
dp.SetValue(UpdatingPassword, value);
}
and below is the XAML:
<PasswordBox x:Name="PasswordBox"
utility:PasswordBoxHelper.BindPassword="true"
utility:PasswordBoxHelper.BoundPassword="{Binding Path=Password,
Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
Upvotes: 3
Reputation: 21
You can't use Binding to password field in PasswordBox because of security. Actually you can, but your password will be stored in memory. Try this http://blog.functionalfun.net/2008/06/wpf-passwordbox-and-data-binding.html
Upvotes: 2