我正在学习Mvvmlight,并且对RelayCommand的canExecute
很困惑。
基本上,我在view
中有一个Button
和一个PasswordBox
,在viewModel
中有一个Command
。我想要的是禁用按钮,如果密码框为空。我的解决方案是将PasswordBox作为commandparmeter传递给按钮,然后在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
的这种行为很困惑,有什么想法吗?
您是否在这一行的堆栈上声明p,并且在调用处理程序时它是否仍然存在?
CommandConfirm = new RelayCommand<object>((p) => ConfirmExecute(p), (p) => ConfirmCanExecute(p));
因为不正确的命令绑定肯定会导致this返回null,从而产生您所看到的错误。
var passwordBox = parameter as PasswordBox;
其次,为什么让ViewModel以这种方式直接操作View ?简单地将Password字段绑定到ViewModel,然后ViewModel的CanExecute处理程序就变成了一行代码,不是吗?
return !String.IsNullOrEmpty(this.Password);