【问题标题】:Weird behavior of canExecute in Mvvmlight RelayCommandMvvmlight RelayCommand 中 canExecute 的奇怪行为
【发布时间】:2014-06-25 06:29:16
【问题描述】:

我正在学习 Mvvmlight,对 RelayCommand 的 canExecute 感到很困惑。

基本上,我在view 中有一个Button 和一个PasswordBox,在viewModel 中有一个Command。如果密码框为空,我想要禁用按钮。我的解决方案是将 PasswordBox 作为 CommandParemeter 传递给 Button,然后在 canExecute 方法中接收 PasswordBox 并指定它是 null 还是空。我首先声明一个命令:

public ICommand CommandClear { get; private set; }

然后在Class Constructor中实例化它:

CommandConfirm = new RelayCommand<object>((p) => ConfirmExecute(p), (p) => ConfirmCanExecute(p));

最终实现canExecute方法如下:

private bool ConfirmCanExecute(object parameter)
{
    bool isExecuable = false;
    var passwordBox = parameter as PasswordBox;
    if (!string.IsNullOrEmpty(passwordBox.Password))
        isExecuable = true;
    return isExecuable;
}

上面的 canExecute 方法不起作用,因为 System.Reflection.TargetInvocationException 会在 PresentationFramework.dll 中抛出未处理的异常。

所以我尝试用try...catch包装上面的代码。这一次,它像魔术一样工作:

        try
        {
            var passwordBox = parameter as PasswordBox;
            if (!string.IsNullOrEmpty(passwordBox.Password))
                isExecuable = true;
            return isExecuable;
        }
        catch
        {
            return isExecuable;
        }

我对@9​​87654336@的这种行为感到很困惑,有什么想法吗?

【问题讨论】:

  • 那么我是否能以正确的方式完成工作?我不明白为什么在之前的canExecute 方法中会抛出异常。
  • 您是否检查过 PasswordBox 是否已正确传递给您的 canExecute 方法?您的方法中唯一看起来可能引发异常的地方是passwordBox.Password,因为您没有检查passwordBox 是否为空。

标签: c# mvvm-light relaycommand canexecute


【解决方案1】:

你是否在这一行的堆栈上声明了 p 并且在调用处理程序时它是否仍然存在?

CommandConfirm = new RelayCommand<object>((p) => ConfirmExecute(p), (p) => ConfirmCanExecute(p));

因为不正确的命令绑定肯定会导致 this 返回 null,从而产生您所看到的错误。

var passwordBox = parameter as PasswordBox;

其次,为什么你的 ViewModel 用这种方式直接操作 View?只需将密码字段 2 路绑定到您的 ViewModel,您的 ViewModel 的 CanExecute 处理程序就变成了单线,不是吗?

return !String.IsNullOrEmpty(this.Password);

【讨论】:

  • WPF中的PasswordBox不支持绑定,所以必然会违反MVVM模式。我引用了this,它在ViewModel中操纵View。其次,我明白你的意思有点,也许有什么技巧可以解决吗?
  • 老实说没什么大不了的——遵循“视图模型永远不会触及视图”的格言有时只是虚构的。但是好的,我们通常在 WPF 中绑定到不可绑定控件的方式是创建一个“可绑定”依赖属性,如此处wpftutorial.net/PasswordBox.html 或此处所示:stackoverflow.com/questions/263551/…。请注意绑定到密码字段的安全隐患!
猜你喜欢
  • 2013-02-10
  • 1970-01-01
  • 2014-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多