WPF重复密码IMultiValueConverter

时间:2018-08-19 18:25:12

标签: c# wpf multibinding passwordbox 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();
    }
}

命令(ChangePassword):

if ((p as string) != "|NOMATCH|")
{
    MessageBox.Show("Password changed");
}
else
{
    MessageBox.Show("Passwords not matching");
}

当我在转换器和命令中设置断点时,得到以下结果: 视图加载后,它会立即跳入转换器并尝试转换两个PasswordBoxes。两者都是空的。 当我按下按钮时(两个密码盒中的内容无关紧要),它不会进入转换器并在命令-if处停止。 P代表一个空密码。

2 个答案:

答案 0 :(得分:2)

仅当多重绑定的源属性更改时,才会调用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

答案 1 :(得分:0)

您的代码中要考虑多个错误的事情:

  • 您的绑定直接绑定到控件元素(在您的情况下为PasswordBox),如果您希望对值进行多次绑定,则应始终使用“路径”属性在其(dep)属性上进行绑定观察(为什么框架否则会触发PropertyChanged事件?您的控件没有更改,但是它们的属性可能会更改)
  • 如果您使用TextBox而不是PasswordBox并将Path =“ Text”添加到绑定中,则会得到您期望的行为
  • 坏消息:由于安全原因,您无法绑定到PasswordBox的Password属性。