WPF中的命令路由与事件路由是两个很让初学者头痛的概念,对于命令路由可以理解为,系统(WPF)定义了一系列的操作,在应用程序中可以直接使用。例如,定义一系列菜单,执行对窗体中文本框的复制、剪切、粘贴操作,简单地可以这样做:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="23" />
<RowDefinition />
</Grid.RowDefinitions>
<Menu Grid.Row="0" Grid.Column="0">
<MenuItem Header="Edit">
<MenuItem x:Name="menuCopy" Header="Copy"
Command="ApplicationCommands.Copy" />
<MenuItem x:Name="menuCut" Header="Cut"
Command="ApplicationCommands.Cut" />
<MenuItem x:Name="menuPaste" Header="Paste"
Command="ApplicationCommands.Paste" />
</MenuItem>
</Menu>
<TextBox Grid.Row="1" Grid.Column="0" x:Name="mainText"
TextWrapping="Wrap" AcceptsReturn="True" />
</Grid>
WPF 中的路由命令模型可以分为四个主要概念:命令、命令源、命令目标以及命令绑定:
命令是要执行的操作。在本例中命令为ApplicationCommands.Copy、Cut、Paste
命令源是调用命令的对象。 在本例中命令源为三个MenuItem控件
命令目标是在其上执行命令的对象。 在本例中命令目标是mainText这个TextBox文本框
命令绑定是将命令逻辑映射到命令的对象。 在本例中命令绑定到系统定义的对于文本框的“复制”、“剪切”、“粘贴”操作、
其四者的关系如下图所示:
- 命令:
- WPF 中的命令是通过实现 ICommand 接口来创建的。ICommand 公开两个方法(Execute 和 CanExecute)和一个事件 (CanExecuteChanged)。Execute 执行与命令关联的操作。CanExecute 确定是否可以在当前命令目标上执行命令。如果集中管理命令操作的命令管理器检测到命令源中发生了更改,此更改可能使得已引发但尚未由命令绑定执行的命令无效,则将引发 CanExecuteChanged。ICommand 的 WPF 实现是 RoutedCommand 类。
- RoutedCommand 上的 Execute 方法在命令目标上引发 PreviewExecuted 和 Executed 事件。RoutedCommand 上的 CanExecute 方法在命令目标上引发 CanExecute 和 PreviewCanExecute 事件。这些事件沿元素树以隧道和冒泡形式传递,直到遇到具有该特定命令的 CommandBinding 的对象。
- WPF 提供了一组常用的路由命令,这组命令分布在几个类中:MediaCommands、ApplicationCommands、NavigationCommands、ComponentCommands 和 EditingCommands。这些类仅包含 RoutedCommand 对象,而不包含命令的实现逻辑。实现逻辑由在其上执行命令的对象负责。
- WPF已封装的命令类有:
命令类 | 示例命令 |
ApplicationCommands | Close、Cut、Copy、Paste、Save、Print |
NavigationCommands | BrowseForward、BrowseBack、Zoom、Search |
EditingCommands | AlignXXX、MoveXXX、SelectXXX |
MediaCommands | Play、Pause、NextTrack、IncreaseVolume、Record、Stop |
ComponentCommands | MoveXXX、SelectXXX、ScrollXXX、ExtendSelectionXXX |
XXX 代表操作的集合,例如 MoveNext 和 MovePrevious。其中ApplicationCommands为默认的命令类,引用其中的命令时可以省略ApplicationCommands。