WPF 重复密码 IMultiValueConverter
WPF Repeat password IMultiValueConverter
我想要一个 PasswordBox 和另一个 PasswordBox 来重复选择的密码和一个提交按钮。
这是我得到的:
WPF:
<UserControl.Resources>
<converter:PasswordConverter x:Key="PasswdConv"/>
</UserControl.Resources>
<PasswordBox PasswordChar="*" Name="pb1"/>
<PasswordBox PasswordChar="*" Name="pb2"/>
<Button Content="Submit" Command="{Binding ChangePassword}">
<Button.CommandParameter>
<MultiBinding Converter="{StaticResource PasswdConv}">
<MultiBinding.Bindings>
<Binding ElementName="pb1"/>
<Binding ElementName="pb2"/>
</MultiBinding.Bindings>
</MultiBinding>
</Button.CommandParameter>
</Button>
转换器:
public class PasswordConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
List<string> s = values.ToList().ConvertAll(p => SHA512(((PasswordBox)p).Password));
if (s[0] == s[1])
return s[0];
return "|NOMATCH|";
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
命令(更改密码):
if ((p as string) != "|NOMATCH|")
{
MessageBox.Show("Password changed");
}
else
{
MessageBox.Show("Passwords not matching");
}
当我在转换器和命令中设置断点时,我得到以下结果:
一旦视图加载,它就会跳入转换器并尝试转换两个 PasswordBoxes。两者都是空的。
当我按下按钮时(两个 PasswordBoxes 中的内容无关紧要)它不会进入转换器并在 command-if 处停止。 P代表空密码。
您的代码中有多个错误需要考虑:
- 您的绑定是直接绑定到控件元素(在您的例子中是 PasswordBox),您应该始终使用 "Path" 属性绑定到它的 (dep) 属性多次应用绑定以观察值(为什么框架要触发 PropertyChanged 事件?您的控件不会更改,但它们的属性可能会更改)
- 如果您使用 TextBox 而不是 PasswordBox 并将 Path="Text" 添加到您的绑定,您将获得预期的行为
- 坏消息:出于安全原因,您无法绑定到 PasswordBox 的密码 属性。
Convert
方法只会在多重绑定的源 属性 发生变化时调用,但您绑定到 PasswordBox
本身并且它永远不会改变。
并且绑定到 Password
属性 也不起作用,因为 PasswordoBox
在 属性 更改时不会引发任何更改通知。
它确实引发了一个 PasswordChanged
事件,所以你可以处理这个并在这个事件处理程序中设置 CommandParameter
属性 而不是使用转换器:
private void OnPasswordChanged(object sender, RoutedEventArgs e)
{
string password = "|NOMATCH|";
List<PasswordBox> pb = new List<PasswordBox>(2) { };
List<string> s = new List<string>[2] { SHA512(pb1.Password), SHA512(pb2.Password) };
if (s[0] == s[1])
password = s[0];
btn.CommandParameter = password;
}
XAML:
<PasswordBox PasswordChar="*" Name="pb1" PasswordChanged="OnPasswordChanged"/>
<PasswordBox PasswordChar="*" Name="pb2" PasswordChanged="OnPasswordChanged"/>
<Button x:Name="btn" Content="Submit" Command="{Binding ChangePassword}" />
如果您希望能够跨多个视图和 PasswordBox
控件重用此功能,您应该编写 attached behaviour.
我想要一个 PasswordBox 和另一个 PasswordBox 来重复选择的密码和一个提交按钮。
这是我得到的:
WPF:
<UserControl.Resources>
<converter:PasswordConverter x:Key="PasswdConv"/>
</UserControl.Resources>
<PasswordBox PasswordChar="*" Name="pb1"/>
<PasswordBox PasswordChar="*" Name="pb2"/>
<Button Content="Submit" Command="{Binding ChangePassword}">
<Button.CommandParameter>
<MultiBinding Converter="{StaticResource PasswdConv}">
<MultiBinding.Bindings>
<Binding ElementName="pb1"/>
<Binding ElementName="pb2"/>
</MultiBinding.Bindings>
</MultiBinding>
</Button.CommandParameter>
</Button>
转换器:
public class PasswordConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
List<string> s = values.ToList().ConvertAll(p => SHA512(((PasswordBox)p).Password));
if (s[0] == s[1])
return s[0];
return "|NOMATCH|";
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
命令(更改密码):
if ((p as string) != "|NOMATCH|")
{
MessageBox.Show("Password changed");
}
else
{
MessageBox.Show("Passwords not matching");
}
当我在转换器和命令中设置断点时,我得到以下结果: 一旦视图加载,它就会跳入转换器并尝试转换两个 PasswordBoxes。两者都是空的。 当我按下按钮时(两个 PasswordBoxes 中的内容无关紧要)它不会进入转换器并在 command-if 处停止。 P代表空密码。
您的代码中有多个错误需要考虑:
- 您的绑定是直接绑定到控件元素(在您的例子中是 PasswordBox),您应该始终使用 "Path" 属性绑定到它的 (dep) 属性多次应用绑定以观察值(为什么框架要触发 PropertyChanged 事件?您的控件不会更改,但它们的属性可能会更改)
- 如果您使用 TextBox 而不是 PasswordBox 并将 Path="Text" 添加到您的绑定,您将获得预期的行为
- 坏消息:出于安全原因,您无法绑定到 PasswordBox 的密码 属性。
Convert
方法只会在多重绑定的源 属性 发生变化时调用,但您绑定到 PasswordBox
本身并且它永远不会改变。
并且绑定到 Password
属性 也不起作用,因为 PasswordoBox
在 属性 更改时不会引发任何更改通知。
它确实引发了一个 PasswordChanged
事件,所以你可以处理这个并在这个事件处理程序中设置 CommandParameter
属性 而不是使用转换器:
private void OnPasswordChanged(object sender, RoutedEventArgs e)
{
string password = "|NOMATCH|";
List<PasswordBox> pb = new List<PasswordBox>(2) { };
List<string> s = new List<string>[2] { SHA512(pb1.Password), SHA512(pb2.Password) };
if (s[0] == s[1])
password = s[0];
btn.CommandParameter = password;
}
XAML:
<PasswordBox PasswordChar="*" Name="pb1" PasswordChanged="OnPasswordChanged"/>
<PasswordBox PasswordChar="*" Name="pb2" PasswordChanged="OnPasswordChanged"/>
<Button x:Name="btn" Content="Submit" Command="{Binding ChangePassword}" />
如果您希望能够跨多个视图和 PasswordBox
控件重用此功能,您应该编写 attached behaviour.