WPF 中命令的 CanExecute 执行逻辑,我一直觉得比较麻烦,画出来就清晰多了,备忘:
public class WalterlvCommand : ICommand { public bool SomeFlag { get; set; } bool ICommand.CanExecute
" CanExecute="PrintCommand_CanExecute" /> </Window.CommandBindings> 这个命令绑定集合为我们的每个命令命名,告诉我们事件触发时该怎么做 在这背后,我们添加了这些方法(我在WPF项目中使用C#,但我可以选择使用X#,因为这里的代码量很小,因此无关紧要): privatevoid NewCommand_CanExecute(object sender , CanExecuteRoutedEventArgs e) { e.CanExecute= true; } privatevoid NewCommand_Executed(object sender, ExecutedRoutedEventArgs e) { MessageBox.Show("New Task"); } privatevoid PrintCommand_CanExecute (object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = true; } privatevoid PrintCommand_Executed
ICommand需要用户定义两个方法bool CanExecute和void Execute。第一个方法可以让我们来判断是否可以执行这个命令,第二个方法就是我们具体的命令。 67 { 68 69 } 70 71 public RelayCommand(Action execute, Func<Boolean> canExecute = canExecute; 82 83 } 84 85 #endregion 86 87 88 89 #region ICommand (Object parameter) 126 127 { 128 129 return _canExecute == null ? true : _canExecute(); 130 131 } 132 133 134 135 public void Execute(Object parameter
event EventHandler CanExecuteChanged; bool CanExecute(object parameter); void Execute The command source can then query the command using the CanExecute method. 按照MSDN中的解释,当CanExecuteChanged事件发生时,ICommandSource会调用ICommand的CanExecute方法来检测是否可以执行命令。 因为CanExecuteChanged发生,使用者的第一感觉就是CanExecute从false变到true或者由true变到false了。
在CanExecuteChanged的事件处理函数及CommandParameter的PropertyChangedCallback中,根据Command.CanExecute(CommandParameter = Command) && Command.CanExecute(CommandParameter)) { Command.Execute(CommandParameter ); } private void UpdateIsEnabled() { IsEnabled = (null == Command) || Command.CanExecute MenuItemSamplePage() { this.InitializeComponent(); var command = new DelegateCommand<object>(Click, CanExecute MessageDialog dialog = new MessageDialog(parameter.ToString()); dialog.ShowAsync(); } private bool CanExecute
定义一个简单的命令 public class Command : ICommand { /// <inheritdoc /> public bool CanExecute UIElement) sender).Focus); } 此时运行代码,点击文本,可以看到输出窗口输出 林德熙是逗比 然后点击文本,输入文字,然后点击按钮,可以发现按钮的命令没有触发 在命令的 CanExecute 打上断点,可以发现连 CanExecute 都没有进入 如果遇到了在按钮 MVVM 绑定命令,发现命令没有触发,同时 CanExecute 都没有进入,可以猜可能是命令没有初始化、命令没有绑对,还有可能是在过程出现焦点问题
本例中,当CommandBinding捕捉到CanExecute就会调用cb_CanExecute方法。当捕捉到是Executed的时候,就调用cb_Execute事件。 第三,因为CanExecute事件的激发频率比较高,为了避免降低性能,在处理完毕之后建议将e.Handle设置为true。 第四,CommandBinding一定要设置在命令目标的外围控件上,不然无法捕捉CanExecute和Executed等路由事件。 --为窗体添加CommandBinding--> <Window.CommandBindings> <CommandBinding Command="New" CanExecute="CommandBinding_CanExecute (txtName.Text)) { e.CanExecute = false; } else { e.CanExecute
">判断命令是否能够执行的方法</param> public Command(Action<object> execute, Func<object, bool> canExecute) { _execute = execute; _canExecute = canExecute; } / (object parameter) { if (_canExecute == null) return true; return _canExecute _execute = execute; _canExecute = canExecute; } /// <summary (object parameter) { if (_canExecute == null) return true; return _canExecute
">判断命令是否能够执行的方法</param>
54 public Command(Action<object> execute, Func<object, bool> canExecute )
55 {
56 _execute = execute;
57 _canExecute = canExecute;
58 (object parameter)
66 {
67 if (_canExecute == null) return true;
68 return _canExecute(parameter);
69 }
70
71 ///
中命令系统的基础是一个相对简单的ICommand的接口,代码如下: public interface ICommand { event EventHandler CanExecuteChanged; bool CanExecute (object parameter); void Execute(object parameter); } CanExecute用于确定命令是否处于可执行的状态。 典型的,UI控件能使用CanExecute来启用或禁用自己。也就是说,在相关的命令从CanExecute中返回False的时候,按钮将变得不可用。 在被调用后关闭应用程序,代码如下: public class Exit : ICommand { event EventHandler CanExecuteChanged; public bool CanExecute 这个例子虽然有点微不足道,不过可以使用CanExecute方法轻松地完成类似的行为,并针对“坏”文件禁用这个命令。然而,这里最重要的一点是,可以返回任何命令。
class RelayCommand : ICommand { private readonly Action _execute; private readonly Func<bool> _canExecute ; public RelayCommand(Action execute, Func<bool> canExecute = null) { _execute = execute; _canExecute = canExecute; } public bool CanExecute(object parameter) = > _canExecute?.
Window.CommandBindings> <CommandBinding Command="{StaticResource btnClick1}" CanExecute ="CommandBinding_CanExecute1" Executed="CommandBinding_Executed1"/> </Window.CommandBindings (object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = true; } ="cb_CanExecute" Executed="myRoudedEvent" /> </Window.CommandBindings> <Grid> <Menu (object sender, CanExecuteRoutedEventArgs e) { e.CanExecute = true; }
object Target; public DependencyObject View; public MethodInfo Method; public Func<bool> CanExecute CanExecute: 一个函数,如果操作可被调用、 虚假否则返回 true。 key index: 一个地方来存储/检索它可以对框架的扩展所使用的任何附加元数据。
implement logic } private bool CanSubmit(string parameter) { return true; } 通常 UI 会根据 ICommand 的 CanExecute CanExecute 返回 DelegateCommand 构造函数中的第二个参数 canExecuteMethod 的返回值。如果不传入这个参数,则 CanExecute 一直返回 True。 如果 CanExecute 的返回值有变化,可以调用 RaiseCanExecuteChanged 函数,它会触发 CanExecuteChanged 事件并通知 UI 元素重新判断绑定的 ICommand RaiseCanExecuteChanged,DelegateCommand 还可以用 ObservesProperty 和 ObservesCanExecute 两种形式监视属性,定于属性的 PropertyChanged 事件并改变 CanExecute
">判断命令是否能够执行的方法</param> public Command(Action<object> execute, Func<object, bool> canExecute) { _execute = execute; _canExecute = canExecute; } / (object parameter) { if (_canExecute == null) return true; return _canExecute _execute = execute; _canExecute = canExecute; } /// <summary (object parameter) { if (_canExecute == null) return true; return _canExecute
第一个成员是个事件处理器,从名字可以看出来该事件处理器关注于第二个成员,也就是当命令能否执行的状态出现改变时可以使用此事件通知到关注此命令执行状态的成员; 第三个成员也是个方法,命令的执行逻辑放在这个方法里边,当CanExecute isCanExec被设置为FALSE,所以命令终止执行,输出窗口无内容: 【命令参数CommandParameter】 如果命令仅仅是这样使用,那就太单调了,大家肯定注意到了Execute和CanExecute
用 source generators 就没这些烦恼了,命令的定义可以简化成这样: [ICommand(CanExecute = nameof(HasName))] private void Display 此外,还可以通过它的 CanExecute 属性指定将 ICommand 的 CanExecute 关联到对应的属性。
系统,在System.WIndows.Interactivity.dll中 原理都很类似,重点是两个 提供了InvokeCommandAction类,可以通过EventTrigger触发Command的CanExecute = null && command.CanExecute(commandParameter)) { command.Execute
= null && routedCmd.CanExecute(parameter, target)) { routedCmd.Execute(parameter, = null && command.CanExecute(parameter)) { command.Execute(parameter); } execute) { _execute = execute; } public bool CanExecute(object?