【问题标题】:PasswordBox Binding密码框绑定
【发布时间】:2009-05-20 15:00:38
【问题描述】:

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

我有一个包含ComboBoxPasswordBox 的登录页面。 ComboBox 看起来像这样:

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

这很好用 - 每次SelectedItemComboBox 上发生更改时,我的值都会更新!

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

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

所以我的问题是我没有将 PasswordBox 绑定到 ViewModel 上的 Password 属性 - 所以我无法判断它何时更新。

那么如何将PasswordBox 的值传递给我的 ViewModel?我读到的所有内容都只是说出于安全原因不要绑定PasswordBox。我会简单地取消对 CanLogin() 的密码限制,但我需要将值传递给 AccountService。

【问题讨论】:

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

标签: wpf mvvm binding passwordbox


【解决方案1】:

有趣。

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

显然链接现在已经失效所以这是原始解决方案(找到here):

您可以使用附加属性来创建这样的助手:

公共静态类 PasswordHelper { 公共静态只读 DependencyProperty PasswordProperty = DependencyProperty.RegisterAttached("密码", typeof(字符串),typeof(密码助手), 新的 FrameworkPropertyMetadata(string.Empty, OnPasswordPropertyChanged)); 公共静态只读 DependencyProperty AttachProperty = DependencyProperty.RegisterAttached("附加", typeof(bool), typeof(PasswordHelper), new PropertyMetadata(false, Attach)); 私有静态只读 DependencyProperty IsUpdatingProperty = DependencyProperty.RegisterAttached("IsUpdating", typeof(bool), 类型(密码助手)); 公共静态无效 SetAttach(DependencyObject dp,布尔值) { dp.SetValue(附加属性,值); } 公共静态布尔 GetAttach(DependencyObject dp) { 返回 (bool)dp.GetValue(AttachProperty); } 公共静态字符串 GetPassword(DependencyObject dp) { 返回(字符串)dp.GetValue(密码属性); } 公共静态无效 SetPassword(DependencyObject dp,字符串值) { dp.SetValue(密码属性,值); } 私有静态布尔 GetIsUpdating(DependencyObject dp) { 返回(布尔)dp.GetValue(IsUpdatingProperty); } 私有静态无效 SetIsUpdating(DependencyObject dp,布尔值) { dp.SetValue(IsUpdatingProperty, value); } 私有静态无效 OnPasswordPropertyChanged(DependencyObject 发件人, DependencyPropertyChangedEventArgs e) { PasswordBox passwordBox = 作为 PasswordBox 的发件人; passwordBox.PasswordChanged -= PasswordChanged; if (!(bool)GetIsUpdating(passwordBox)) { passwordBox.Password = (string)e.NewValue; } passwordBox.PasswordChanged += PasswordChanged; } 私人静态无效附加(DependencyObject发件人, DependencyPropertyChangedEventArgs e) { PasswordBox passwordBox = 作为 PasswordBox 的发件人; 如果(密码框 == 空) 返回; if ((bool)e.OldValue) { passwordBox.PasswordChanged -= PasswordChanged; } if ((bool)e.NewValue) { passwordBox.PasswordChanged += PasswordChanged; } } 私有静态无效密码更改(对象发送者,RoutedEventArgs e) { PasswordBox passwordBox = 作为 PasswordBox 的发件人; SetIsUpdating(密码框,真); 设置密码(密码框,密码框.密码); SetIsUpdating(密码框,假); } }

使用它:

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

【讨论】:

  • 我知道这是一个非常古老的答案并且有效,但是有人注意到代码有多古怪吗?也许我应该发布一个不太复杂的版本?
  • 上面的代码不起作用(PasswordHelper),请改用链接中的方法(PasswordBoxAssistant)。 blog.functionalfun.net/2008/06/…
  • 是的,PasswordHelper 导致 StackOverflow 异常(由于 TwoWay 模式),但正如 @morph85 所建议的那样,PasswordBoxAssistent 就像一个魅力。
【解决方案2】:

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

【讨论】:

  • 不错的解决方案。关于如何轻松提升嵌入式 PasswordBox 的属性(例如前景、背景)以便在 XAML 中访问它们的任何提示?
猜你喜欢
  • 2017-04-20
  • 1970-01-01
  • 1970-01-01
  • 2016-05-29
  • 1970-01-01
  • 1970-01-01
  • 2016-11-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多