密码框绑定

12

我刚刚开始使用M-V-VM和WPF,但在理解一些绑定问题方面遇到了困难。

我有一个登录页面,其中包含一个ComboBox和一个PasswordBoxComboBox如下所示:

<ComboBox Name="comboBox1" SelectedItem="{Binding Path=Username}">

这很好用 - 每次ComboBoxSelectedItem更改,我的值就会被更新!

在我的ViewModel中,我有一个ICommand,它使用此方法确定登录按钮是否处于活动状态:

public bool CanLogin()
{
    return !string.IsNullOrEmpty(Username) && !string.IsNullOrEmpty(Password);
}

我的问题是我没有将PasswordBox绑定到ViewModel上的Password属性 - 所以我没有办法知道它何时被更新。

那么,我该如何将PasswordBox的值传递给ViewModel?我读过的所有内容都只是说出于安全原因不要绑定PasswordBox。我只需解除CanLogin()中的密码限制,但我需要将值传递给AccountService。


如果您将密码绑定为字符串(而不是SecureString),则会在进程的内存中暴露密码。这两种解决方案都会危及安全。 - Rubinsh
2个回答

29

有趣。

看看这篇博客文章,看看它是否对你有帮助。 http://blog.functionalfun.net/2008/06/wpf-passwordbox-and-data-binding.html

显然,该链接现在已经失效了,因此这里是原始解决方案(在此处发现):

您可以使用附加属性创建一个类似于以下代码的帮助程序:

public static class PasswordHelper
{
    public static readonly DependencyProperty PasswordProperty =
        DependencyProperty.RegisterAttached("Password",
        typeof(string), typeof(PasswordHelper),
        new FrameworkPropertyMetadata(string.Empty, OnPasswordPropertyChanged));
public static readonly DependencyProperty AttachProperty = DependencyProperty.RegisterAttached("Attach", typeof(bool), typeof(PasswordHelper), new PropertyMetadata(false, Attach));
private static readonly DependencyProperty IsUpdatingProperty = DependencyProperty.RegisterAttached("IsUpdating", typeof(bool), typeof(PasswordHelper));
public static void SetAttach(DependencyObject dp, bool value) { dp.SetValue(AttachProperty, value); }
public static bool GetAttach(DependencyObject dp) { return (bool)dp.GetValue(AttachProperty); }
public static string GetPassword(DependencyObject dp) { return (string)dp.GetValue(PasswordProperty); }
public static void SetPassword(DependencyObject dp, string value) { dp.SetValue(PasswordProperty, value); }
private static bool GetIsUpdating(DependencyObject dp) { return (bool)dp.GetValue(IsUpdatingProperty); }
private static void SetIsUpdating(DependencyObject dp, bool value) { dp.SetValue(IsUpdatingProperty, value); }
private static void OnPasswordPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { PasswordBox passwordBox = sender as PasswordBox; passwordBox.PasswordChanged -= PasswordChanged;
if (!(bool)GetIsUpdating(passwordBox)) { passwordBox.Password = (string)e.NewValue; } passwordBox.PasswordChanged += PasswordChanged; }
private static void Attach(DependencyObject sender, DependencyPropertyChangedEventArgs e) { PasswordBox passwordBox = sender as PasswordBox;
if (passwordBox == null) return;
if ((bool)e.OldValue) { passwordBox.PasswordChanged -= PasswordChanged; }
if ((bool)e.NewValue) { passwordBox.PasswordChanged += PasswordChanged; } }
private static void PasswordChanged(object sender, RoutedEventArgs e) { PasswordBox passwordBox = sender as PasswordBox; SetIsUpdating(passwordBox, true); SetPassword(passwordBox, passwordBox.Password); SetIsUpdating(passwordBox, false); } }

使用它:

<PasswordBox w:PasswordHelper.Attach="True" 
             w:PasswordHelper.Password="{Binding Text, ElementName=plain, Mode=TwoWay}" 
             Width="100"/>

我知道这是一个非常老的答案并且有效,但有没有人注意到代码有多么古怪?也许我应该发布一个更简单的版本? - A.R.
3
以上的代码(PasswordHelper)无法使用,请改用链接中的方法(PasswordBoxAssistant)。http://blog.functionalfun.net/2008/06/wpf-passwordbox-and-data-binding.html - morph85
是的,PasswordHelper因为双向模式导致了StackOverflow异常,但正如@morph85建议的那样,PasswordBoxAssistent运行得非常好。 - NSKBpro

9

我在这里发布了一个GIST,它是一个可绑定的密码框。这里


1
不错的解决方案。有什么提示可以轻松提升嵌入式PasswordBox的属性(例如Foreground,Background),以便在XAML中访问它们吗? - Pete Magsig

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接