Frage Wie man PasswordBox WPF validiert


Ich versuche eine Validierung für eine PasswordBox. Um dies zu bestätigen, habe ich das verfolgt Verknüpfung, das zeigt, wie man validiert TextBox.

Das Problem kommt mit PasswordBoxes. So wie es ist Password aus Sicherheitsgründen nicht bindbar, habe ich versucht, eine verbindliche Folge zu machen dieser Link (auch erklärt Hier, für CodeProject Benutzer).

Also, anscheinend, fantastisch! Ich kann meine binden PasswordBox mit Password Eigenschaft, also kann ich mich mit meiner Validierung verbinden. Aber es ignoriert mich ...

Dies ist eine regelmäßige TextBox das ich benutze und gut funktioniert:

<local:ErrorProvider Grid.Column="1" Grid.Row="2" >
    <TextBox Width="160" 
          HorizontalAlignment="Left" 
           Name="textBoxUserPass" 
           Text="{Binding Path=Password, UpdateSourceTrigger=Explicit}" />
 </local:ErrorProvider>

Und das ist das PasswordBox Ich habe versucht zu simulieren:

<local:ErrorProvider Grid.Column="1" Grid.Row="2" >
      <PasswordBox Width="160"
          HorizontalAlignment="Left"
          Name="textBoxUserPass"
          local:PasswordBoxAssistant.BindPassword="True"
          local:PasswordBoxAssistant.BoundPassword="{Binding Path=Password, UpdateSourceTrigger=Explicit}" />
 </local:ErrorProvider>

So bekomme ich das BindingExpression für jede TextBox:

BindingExpression beUserName = textBoxUserName.GetBindingExpression(TextBox.TextProperty);
if (beUserName != null) beUserName.UpdateSource();

Und so bekomme ich es für die PasswordBox:

BindingExpression bePassword = textBoxUserPass.GetBindingExpression(PasswordBoxAssistant.BoundPassword);
if (bePassword != null) bePassword.UpdateSource();

Wenn wir einen Fehler gemacht haben (definiert in meiner Validierungsklasse), wenn ich dies tue:

if (!beUserName.HasError && !bePassword.HasError)

jeder BindingExpression sollte sagen wahr von falsch abhängig von Fehlervalidierungen. Aber für meine PasswordBox bekommt nie den Wert ... Irgendeine Idee?


11
2018-02-27 12:35


Ursprung


Antworten:


Versuchen Sie die Einstellung ValidatesOnDataErrors=True und ValidatesOnExceptions=True auf deine Bindung:

<PasswordBox ...
   local:PasswordBoxAssistant.BoundPassword="{Binding Path=Password,
      UpdateSourceTrigger=Explicit, 
      ValidatesOnDataErrors=True, 
      ValidatesOnExceptions=True}"
/>

11
2018-02-27 14:50



Eine andere Lösung, ohne einen "unsicheren" String in der Mitte zu verwenden, besteht darin, den Window-Code anzupassen, etwa so:

Nehmen wir an, ich habe ein MVVM-Objekt wie dieses, mit WPF-Validierung mit IDataErrorInfo:

public class MyObject : INotifyPropertyChanged, IDataErrorInfo
{
    ...
    public SecureString SecurePassword
    {
        get
        { ... }
        set
        {
            ...
            OnPropertyChanged("SecurePassword");
        }
    }

    ...

    string IDataErrorInfo.Error { get { return Validate(null); } }
    string IDataErrorInfo.this[string columnName] { get { return Validate(columnName); } }

    private string Validate(string memberName)
    {
        string error = null;
        ...
        if (memberName == "SecurePassword" || memberName == null)
        {
            // this is where I code my custom business rule
            if (SecurePassword == null || SecurePassword.Length == 0)
            {
                error = "Password must be specified.";
            }
        }
        ...
        return error;
    }

}

Und ein Window Xaml mit einer PasswordBox wie folgt:

<PasswordBox Name="MyPassword" PasswordChanged="MyPassword_Changed" ... />

Dann wird der entsprechende Window-Code wie folgt die PasswordBox-Bindung auslösen:

// add a custom DependencyProperty
public static readonly DependencyProperty SecurePasswordProperty =
    DependencyProperty.RegisterAttached("SecurePassword", typeof(SecureString), typeof(MyWindow));

public MyWindow()
{
    InitializeComponent();

    DataContext = myObject; // created somewhere

    // create a binding by code
    Binding passwordBinding = new Binding(SecurePasswordProperty.Name);
    passwordBinding.Source = myObject;
    passwordBinding.ValidatesOnDataErrors = true;
    // you can configure other binding stuff here
    MyPassword.SetBinding(SecurePasswordProperty, passwordBinding);
}

private void MyPassword_Changed(object sender, RoutedEventArgs e)
{
    // this should trigger binding and therefore validation
    ((MyObject)DataContext).SecurePassword = MyPassword.SecurePassword;
}

2
2018-05-15 17:01



Soweit ich mich erinnere, ist die einzige Möglichkeit, die Validierung für eine PasswordBox hinzuzufügen, eine neue ValidationException in den Setter der Bindungseigenschaft für SecurePassword zu werfen. Der PasswordBoxAssistant hilft Ihnen dabei nicht.


1
2018-02-27 13:49



Setzen Sie Mode = TwoWay auf Ihre Bindung

local:PasswordBoxAssistant.BoundPassword="{Binding Path=Password,Mode=TwoWay,
UpdateSourceTrigger=Explicit}"

1
2017-07-03 19:36