能否为WPF的InteractionTrigger设置CanExecute?
WPF InteractionTrigger的CanExecute设置及空Command处理方案
默认的InvokeCommandAction不会自动处理CanExecute逻辑,而且如果你的ButtonCommand为空,触发KeyTrigger时肯定会抛空引用异常。下面给你几种实用的解决办法:
一、先解决空Command的报错问题
1. 给Command设个默认空实现
在ViewModel里初始化ButtonCommand的时候,给它赋值一个啥也不做的空命令:
public ICommand ButtonCommand { get; set; } = new RelayCommand(() => {}, () => false);
这样就算没绑定实际命令,触发回车时也不会报错,只是啥反应都没有,很安全。
2. 自定义安全版InvokeCommandAction
自己写个继承InvokeCommandAction的类,在执行前先检查Command是否存在,同时顺便做CanExecute校验:
public class SafeInvokeCommandAction : InvokeCommandAction { protected override void Invoke(object parameter) { // 先判断命令不为空,且CanExecute返回true,再执行 if (Command != null && Command.CanExecute(CommandParameter)) { base.Invoke(parameter); } } }
然后XAML里替换原来的InvokeCommandAction就行:
<i:Interaction.Triggers> <i:KeyTrigger Key="Return"> <local:SafeInvokeCommandAction Command="{TemplateBinding ButtonCommand}" /> </i:KeyTrigger> </i:Interaction.Triggers>
这个方法一举两得,既避免了空Command报错,又实现了CanExecute的校验。
二、让Trigger根据CanExecute状态触发
如果想让回车触发的动作只在CanExecute为true时才生效,除了上面的自定义Action,还可以用DataTrigger来控制:
<i:Interaction.Triggers> <i:DataTrigger Binding="{Binding ButtonCommand.CanExecute, Mode=OneWay}" Value="True"> <i:KeyTrigger Key="Return"> <i:InvokeCommandAction Command="{TemplateBinding ButtonCommand}" /> </i:KeyTrigger> </i:DataTrigger> </i:Interaction.Triggers>
注意这里要求你的Command能正确触发CanExecuteChanged事件,比如用MVVM框架里的RelayCommand或者DelegateCommand一般都自带这个功能。
总结下:
- 默认的
InvokeCommandAction既不处理CanExecute,也不防空,必须手动处理 - 最简单的兜底是给Command设空实现
- 自定义Action是最灵活的方案,同时解决两个问题
- DataTrigger可以实现Trigger级别的条件控制
内容的提问来源于stack exchange,提问作者Richard Gale
相关产品推荐
相关产品推荐

