Как проверить пароль 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
никогда не получается значение... Есть идеи?
Ответы
Ответ 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 не поможет вам с этим.