如何验证PasswordBox WPF

时间:2013-02-27 12:35:30

标签: c# wpf validation

我正在尝试对PasswordBox进行验证。为了进行验证,我按照link进行了验证,其中显示了如何在TextBox上进行验证。

问题来自于PasswordBoxes。由于安全原因,Password无法绑定,因此我尝试在this link之后进行绑定(对于CodeProject用户,也解释为here)。

所以,显然,真棒!我可以将PasswordBox与其Password属性绑定,然后我可以绑定我的验证。但它忽略了我......

这是我使用的常规TextBox并且工作正常:

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

这是我试图模拟的PasswordBox

<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>

这是我为每个BindingExpression获取TextBox的方式:

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

这就是我为PasswordBox获取它的方式:

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

如果我们犯了任何错误(在我的验证课程中定义),当我这样做时:

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

每个BindingExpression应该说 false true ,具体取决于错误验证。但是对于我的PasswordBox永远不会有价值......任何想法?

4 个答案:

答案 0 :(得分:11)

尝试在绑定上设置ValidatesOnDataErrors=TrueValidatesOnExceptions=True

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

答案 1 :(得分:2)

在你的装订上设置Mode = TwoWay

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

答案 2 :(得分:2)

另一种解决方案是在中间不使用任何“不安全”的字符串,就是调整Window代码,如下所示:

假设我有一个像这样的MVVM对象,使用IDataErrorInfo进行WPF验证:

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;
    }

}

带有PasswordBox的Window Xaml如下:

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

然后,像这样的相应Window代码将触发PasswordBox绑定:

// 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;
}

答案 3 :(得分:1)

据我记忆,在PasswordBox上添加验证的唯一方法是在SecurePassword的binding属性的setter中抛出一个新的ValidationException。 PasswordBoxAssistant对此没有帮助。