2

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

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

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;
        }

我对这种行为感到很困惑canExecute,有什么想法吗?

4

1 回答 1

3

您是否在这一行的堆栈上声明 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);
于 2014-05-08T03:21:19.390 回答