本质上将命令转为事件流转处理
- ICommandSource 在工作时,比如按钮执行 click 时,会取出本身的 Command ,然后执行 Command.Execute (优先转为 RoutedCommand.ExecuteCore处理)并将 CommandParameter 与 CommandTarget 传入
- 如果 CommandTarget == null, 使用 Keyboard.FocusedElement
- RoutedCommand.ExecuteCore 中使用 CommandTarget 并尝试转为 UiElement, 调用 CommandTarget.RaiseEvent (参数为 ExecutedRoutedEventArgs) 将它转为了事件处理流程
// 绑定命令
private void BindingCommands()
{
// 1. 创建命令
RoutedCommand clearCommand = new(
"Clear", // 命令名称
typeof(RoutedCommandWindow), // 命令所在的类型
new InputGestureCollection { new KeyGesture(Key.C, ModifierKeys.Alt), } // 快捷键 Alt+C
);
// 2. 由 ICommandSource 对象(如 Button)的 Command 属性绑定命令
this.Button.Command = clearCommand;
this.Button.CommandParameter = "Clear text box"; // 可选的命令参数
this.Button.CommandTarget = this.TextBox; // 命令目标对象( 实现IInputElement 接口), 如果不指定,则当为前焦点对象
// 3. 绑定命令到 CommandBinding, 并添加 Executed 与 CanExecute 事件处理程序
var commandBinding = new CommandBinding
{
Command = clearCommand,
};
// 3.1 绑定 Executed 事件处理程序, 这里是清空 TextBox 内容
commandBinding.Executed += (sender, e) => { this.TextBox.Text = string.Empty; };
// 3.2 绑定 CanExecute 事件处理程序, 这里是判断 TextBox 是否有内容
commandBinding.CanExecute += (sender, e) => { e.CanExecute = !string.IsNullOrEmpty(this.TextBox.Text); };
// 4. 指定命令的处理控件
this.Grid.CommandBindings.Add(commandBinding);
// 4.1 提供一种机制,将快捷方式与命令关联起来
this.Grid.InputBindings.Add(new KeyBinding(clearCommand, new KeyGesture(Key.C, ModifierKeys.Alt)));
}
private void CommandBinding_OnCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = !string.IsNullOrEmpty(this.TextBox.Text);
}
private void CommandBinding_OnExecuted(object sender, ExecutedRoutedEventArgs e)
{
this.TextBox.Text = string.Empty;
}
XAML
<Window.CommandBindings>
<!-- 1. 定义命令对应的处理函数 -->
<CommandBinding Command="Delete" Executed="CommandBinding_OnExecuted" CanExecute="CommandBinding_OnCanExecute" />
</Window.CommandBindings>
<Window.InputBindings>
<!-- 可以使用快捷键绑定命令 -->
<KeyBinding Key="T" Modifiers="Control" Command="Delete" />
</Window.InputBindings>
<!-- 2. 绑定命令到按钮 -->
<Button Grid.Row="2" Content="Delete" Command="Delete" />
XAML 中定义命令
<Window.Resources>
<!-- 资源中定义一个命令 -->
<RoutedUICommand x:Key="UpdateCommand" />
</Window.Resources>
<CommandBinding Command="{StaticResource UpdateCommand}" />
<Button Command="{StaticResource UpdateCommand}" Content="update" />
代码执行命令
if (this.FindResource("UpdateCommand") is RoutedUICommand command)
{
var target = Keyboard.FocusedElement;
command.Execute(new object(), target);
}