带数据模板的 MVVM 密码框

MVVM Passwordbox with data template

如何从密码箱中获取密码?
1。我不想违反 MVVM 模式(至少不要太多)
2。我不能使用代码隐藏,因为我使用数据模板来创建我的视图。我必须使用它们,因为我正在制作包含页面的 window。因此,我将页面视图模型存储在我的 window 视图模型中,并在我需要导航到它们中的任何一个时将它们附加到 ContentControl。我必须这样做,因为我在他们之间共享我的模型。
3。我也想要一定程度的安全性,所以我不想 "hack" 密码框来绑定密码 属性。
这不可能吗?

我不使用任何 MVVM 框架。我知道有很多关于 passwordbox 和 MVVM 的问题,但其中 none 涉及数据模板。更重要的是,我有 2 个密码框(第二个 "confirm password"),我不能只将 PasswordBox 作为 CommandParameter 传递(因为我有 2 个密码框并且传递包含它们的元素绝对是野蛮的)

严重的,密码箱没有真正的mvvm解决方案,它像没有mvvm一样保持安全。

在我看来 在 mvvm 构建的应用程序中使用密码框的最好/最不坏的方法是通过命令参数将整个密码框控制权交给您的视图模型 (就像在 login/register 按钮中一样)并将它交给你的内部 classes/services 直到你真的需要为网络服务或类似的东西获取密码。

它肯定会破坏 mvvm 模式,因为您的视图模型知道控件,但它是最安全的解决方案,可以在大多数 mvvm 构建的应用程序中轻松实现。

编辑: 如果需要,您可以通过命令参数轻松传递两个或多个密码框。 (就像注册对话框一样,用户必须输入两次密码并且必须匹配。)这可以通过命令参数的 MultiBinding 来完成:

<Button.CommandParameter>
    <MultiBinding Converter="{local:ItemsToListConverter}">
        <Binding ElementName="nameOfPasswordBox1" />
        <Binding ElementName="nameOfPasswordBox2" />
    </MultiBinding>
</Button.CommandParameter>

转换器只是 returns 所有值作为一个新列表:

[MarkupExtensionReturnType(typeof(ItemsToListConverter))]
public class ItemsToListConverter : MarkupExtension, IMultiValueConverter
{
    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }

    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (values == null) return values;
        return values.ToList();
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

在您的 ViewModel 中,您有一个普通的 ICommand,它将一个对象作为参数。您可以在那里将该对象转换为 PasswordBoxes 列表。 (在我的示例中,它是一个带有方法 'Register' 的 RegisterCommand):

private void Register(object obj)
{
    IEnumerable<PasswordBox> passwordBoxes = (obj as IList).Cast<PasswordBox>();
    //Do whatever with your PasswordBoxes =)
}