在Mvvmlight RelayCommand中canExecute的奇怪行为

时间:2014-05-08 03:05:23

标签: c# mvvm-light relaycommand canexecute

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

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

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的这种行为感到很困惑,有什么想法吗?

1 个答案:

答案 0 :(得分:3)

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

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

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

var passwordBox = parameter as PasswordBox;

其次,为什么ViewModel会以这种方式直接操作View?只需双向将密码字段绑定到ViewModel,您的ViewModel的CanExecute处理程序就变成了一行,不是吗?

return !String.IsNullOrEmpty(this.Password);