【问题标题】:MVVM, Behavior and passwordBoxMVVM、行为和密码框
【发布时间】:2019-01-02 12:32:20
【问题描述】:

我搜索了从 PasswordBox 设置和检索密码字符串的 MVVM 解决方案。 我使用 System.Windows.Interactivity 中的 Behavior 类找到的解决方案。 这是代码: 查看:

<PasswordBox Name="pass" >
        <i:Interaction.Behaviors>
            <vm:PasswordBehavior Password="{Binding Password, Mode=TwoWay}" />
        </i:Interaction.Behaviors>
    </PasswordBox>

这里是 ViewModel:

public class PasswordBehavior : Behavior<PasswordBox>
{
    public static readonly DependencyProperty PasswordProperty =
        DependencyProperty.Register("Password", typeof(string), typeof(PasswordBehavior), new PropertyMetadata(default(string)));

    private bool _skipUpdate;

    public string Password
    {
        get { return (string)GetValue(PasswordProperty); }
        set { SetValue(PasswordProperty, value); }
    }

    protected override void OnAttached()    
    {
        AssociatedObject.PasswordChanged += PasswordBox_PasswordChanged;
    }

    protected override void OnDetaching()
    {
        AssociatedObject.PasswordChanged -= PasswordBox_PasswordChanged;
    }

    protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
    {
        base.OnPropertyChanged(e);

        if (e.Property == PasswordProperty)
        {
            if (!_skipUpdate)
            {
                _skipUpdate = true;
                AssociatedObject.Password = e.NewValue as string;
                _skipUpdate = false;
            }
        }
    }

    private void PasswordBox_PasswordChanged(object sender, RoutedEventArgs e)
    {
        _skipUpdate = true;
        Password = AssociatedObject.Password;
        _skipUpdate = false;
    }
}

这是有效的!我可以在 VM 中看到密码,但这是另一个问题:现在我在 VM 中有两个独立的类:一个来自上面的代码,第二个 Class MainLoginFormViewModel : BaseViewModel 包含所有其他属性,如用户名和检查连接的命令等.

namespace MyApp.ViewModels
{
public class PasswordBehavior : Behavior<PasswordBox>
{
    ...
}
class MainLoginFormViewModel : BaseViewModel
{
    public MainWindowViewModel()
    {
        sStatus = "Hello";
        GetLoginData();
    }

    private string _sStatus;
    public string sStatus
    {
        get { return _sStatus; }
        set { _sStatus = value; NotifyPropertyChanged("sStatus"); }
    }

    private string _sServer;
    public string sServer
    {
        get { return _sServer; }
        set { _sServer = value; NotifyPropertyChanged("sServer"); }
    }
    private string _sName;
    public string sName
    {
        get { return _sName; }
        set { _sName = value; NotifyPropertyChanged("sName"); }
    }

//...
}
}

我不能混合这两个类,因为其中一个嵌套在 BaseViewModel 中,需要实现 INotifyPropertyChanged,第二个嵌套在 Behavior 中,我也需要。

如何使用授权逻辑将 PasswordBehavior 类中的密码值获取到 Main MainLoginFormViewModel 中?我好像错过了什么,但我无法理解是什么......

附:我知道还有另一种方法可以解决 MVVM 中的 PasswordBox 问题,例如将整个密码框控件传递给 viewmodel,但这样我就无法从 VM 设置密码(让应用程序“记住”应用程序启动时的最后一个密码)

【问题讨论】:

  • 行为是只能查看的东西,你不想让它们在 vm 中。但是您可以访问 vm 的内部行为,通常作为关联对象的 DataContext 获得,然后转换为某个接口(vm 应该实现它),如果转换成功 - 调用它的成员。 PasswordBox 很特别,如果您不想搞砸安全性,最好不要 hold 字符串,而是将它的实例传递给 vm。是的,这不常见,但有密码框就可以了。
  • 真的!我将 PasswordBehavior 类移到了代码隐藏视图中,并在 VM 中创建了属性密码,一切都按预期工作。
  • 关于安全问题。我同意你的看法,但在与客户讨论后,我发现:没人关心。这将是内部网络,没有直接连接到网络,客户说 - 如果有人试图从内存中获取通行证,这不是我的问题。只需要用户可以轻松访问其 PC 上的应用程序,并且没有人可以从屏幕上读取密码。

标签: c# mvvm behavior passwordbox


【解决方案1】:

刚刚将 PasswordBehavior 类移到后面的视图代码中并在 VM 中创建属性“密码”:

    private string _Password;
    public string Password
    {
        get { return _Password; }
        set { _Password = value; NotifyPropertyChanged("Password"); }
    }

一切正常。

【讨论】:

    猜你喜欢
    • 2010-11-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-10
    • 2013-06-03
    • 1970-01-01
    相关资源
    最近更新 更多