如何验证 PasswordBox WPF

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15112292/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 07:45:02  来源:igfitidea点击:

How to validate PasswordBox WPF

c#wpfvalidation

提问by Sonhja

I'm trying to make a validation for a PasswordBox. For making validations I followed this link, that shows how to validate on TextBox.

我正在尝试对PasswordBox. 为了进行验证,我遵循了此链接,该链接显示了如何在TextBox.

The problem comes with PasswordBoxes. Because its Passwordis not bindable due to security reasons, I tried to make a binding following this link(also explained here, for CodeProject users).

问题来自PasswordBoxes. 由于Password出于安全原因它不可绑定,我尝试按照此链接进行绑定(也在此处为 CodeProject 用户进行了解释)。

So, apparently, fantastic! I can bind my PasswordBoxwith its Passwordproperty, so then I can bind with my validation. But it ignores me...

所以,显然,太棒了!我可以将 myPasswordBox与其Password属性绑定,然后我可以绑定我的验证。但是它不理我...

This is a regular TextBoxthat I use and works fine:

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

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

And this is the PasswordBoxI tried to simulate:

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

This is how I get the BindingExpressionfor each TextBox:

这就是我获得BindingExpression每个的方式TextBox

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

And this is how I get it for the PasswordBox:

这就是我获得它的方式PasswordBox

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

If we made any mistake (defined on my Validation class), when I do this:

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

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

each BindingExpressionshould say trueof falsedepending on error validations. But for my PasswordBoxnever gets the value... Any idea?

每一个BindingExpression应该说真正取决于错误的验证。但我PasswordBox从来没有得到过价值......知道吗?

采纳答案by Richard Deeming

Try setting ValidatesOnDataErrors=Trueand ValidatesOnExceptions=Trueon your binding:

尝试设置ValidatesOnDataErrors=TrueValidatesOnExceptions=True绑定:

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

回答by KevinChuelo

Set Mode=TwoWay on your binding

在绑定上设置 Mode=TwoWay

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

回答by Simon Mourier

Another solution, without using any "unsecure" string in the middle, is to adapt the Window code, something like this:

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

Let's suppose I have an MVVM object like this, with WPF validation using IDataErrorInfo:

假设我有一个像这样的 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;
    }

}

And a Window Xaml with a PasswordBox like this:

还有一个带有 PasswordBox 的 Window Xaml,如下所示:

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

Then, the corresponding Window code like this will trigger PasswordBox binding:

然后,对应的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;
}

回答by Cristian Chereches

As far as I remember, the only way to add validation on a PasswordBox is to throw a new ValidationException in the setter of the binding property for SecurePassword. The PasswordBoxAssistant will not help you with this.

据我所知,在 PasswordBox 上添加验证的唯一方法是在 SecurePassword 的绑定属性的 setter 中抛出一个新的 ValidationException。PasswordBoxAssistant 不会帮您解决这个问题。