我正在学习Mvvmlight,并对其canExecute
的RelayCommand感到很困惑。
基本上,Button
中有PasswordBox
和view
,Command
中有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
的这种行为感到很困惑,有什么想法吗?
答案 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);