Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I validate a PasswordBox using IDataErrorInfo without an AttachedProperty or DependencyProperty?

I am creating a Registration form containing username, password box, & confirm password box in WPF.

I am planning to use IDataErrorInfo on the view model for validation, but as PasswordBox's Password property is not a DependencyProperty (due to security reasons).

I don't want to use an AttachedProperty, so the only option I can think of is using code behind to pass the password value to ViewModel, but I don't know how to raise a validation error like this.

How can I raise validation for a PasswordBox control without a binding?

I can use validation Rule instead of IDataErrorInfo (if required).

like image 736
user1916083 Avatar asked Dec 19 '12 14:12

user1916083


1 Answers

It is better to answer late than never :)

If you want to avoid exposing the password as plain text in memory in run time then you choose using PasswordBox.SecurePassword property. And you may still want to make some validations over entered value, for example to check it is long enough (SecureString class has Length property). In that case the simplest way for me to apply ErrorTemplate is using an extra property in viewmodel and binding any other property of PasswordBox on it. In general I prefer to use Tag property, but any waste property will suit.

So, code looks like

ViewModel:

public class MyViewModel : ViewModelBase, IDataErrorInfo
{
    // some code skipped

    private SecureString password;
    public SetPassword(SecureString pwd)
    {
        password = pwd.Copy();
        password.MakeReadOnly();
        OnPropertyChanged("PasswordExtra");
    }

    public bool PasswordExtra
    {
        get { return false; }
    }

    #region IDataErrorInfo
    // public string Error realization skipped

    public string this[string propertyName]
    {
        get
        {
            if (propertyName == "PasswordExtra")
            {
                if (password.Length < 8)
                    return "Password is too short";
            }
            return null;
        }
    }
    #endregion IDataErrorInfo
}

View:

private void onPasswordChanged(object sender, RoutedEventArgs e)
{
    (DataContext as MyViewModel).SetPassword((sender as PasswordBox).SecurePassword);
}

XAML:

<PasswordBox
    Tag="{Binding PasswordExtra, ValidatesOnDataErrors=True}"
    PasswordChanged="onPasswordChanged"/>
like image 117
Sergey Avatar answered Nov 02 '22 01:11

Sergey