user3030371
user3030371

Reputation: 21

password box does not mask my password WPF

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

Answers (4)

Ivan
Ivan

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.

First Appearance

Select the text box by clicking

Entered Value

Reveal

Upvotes: 0

St&#233;phane Gourichon
St&#233;phane Gourichon

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:

XAML:

<PasswordBox PasswordChanged="OnPasswordChanged" />

Code-behind event handler:

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

J R B
J R B

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

Borys Yermakov
Borys Yermakov

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

Related Questions