Подтвердить что ты не робот

Как проверить пароль WPF WPF

Я пытаюсь сделать проверку для PasswordBox. Для проверки я перешел по этой ссылке, которая показывает, как проверить на TextBox.

Проблема приходит с PasswordBoxes. Поскольку его Password не может быть привязан по соображениям безопасности, я попытался создать привязку по этой ссылке (также объясненной здесь, для пользователей CodeProject).

Так что, видимо, фантастика! Я могу связать свой 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 должно BindingExpression true или false в зависимости от проверки ошибок. Но для моего PasswordBox никогда не получается значение... Есть идеи?

4b9b3361

Ответ 1

Попробуйте установить ValidatesOnDataErrors=True и ValidatesOnExceptions=True в вашей привязке:

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

Ответ 2

Режим установки = TwoWay на вашей привязке

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

Ответ 3

Другим решением, без использования какой-либо "незащищенной" строки в середине, является адаптация кода окна, примерно так:

Предположим, что у меня есть объект MVVM, подобный этому, с проверкой WPF с помощью 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;
    }

}

И Window Xaml с PasswordBox следующим образом:

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

Затем соответствующий код окна, подобный этому, вызовет привязку 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;
}

Ответ 4

Насколько я помню, единственный способ добавить валидацию в PasswordBox - это бросить новое ValidationException в установщике свойства привязки для SecurePassword. PasswordBoxAssistant не поможет вам с этим.