MVVM之ICommand
最近在学习MVVM模式,看到其中比较重要的一个知识点就是ICommand,由于刚刚接触,不是很理解,
所以搜集了一些很好的资料,在此整理一下。
Silverlight 4.0 MVVM 模式:
- ICommand - 命令。可以将其绑定到 ButtonBase 或 Hyperlink 的 Command 属性上
- MVVM 模式 - Model-View-ViewModel
MVVM基础学习,本人是看了http://www.cnblogs.com/626498301/archive/2010/08/18/1802204.html
讲得很好,很简单也很细致,还有例子。
ICommand 知识,参照MSDN(http://msdn.microsoft.com/zh-cn/library/ms616869.aspx)
ICommand 公开两个方法(Execute 及 CanExecute)和一个事件(CanExecuteChanged)。
bool CanExecute(object parameter) - 当前命令是否可以执行。
void Execute(object parameter) - 当前命令被执行时,所调用的方法。
event EventHandler CanExecuteChanged - (当前命令是否可以执行即CanExecute)的状态发生改变时所触发的事件。
当用ICommand时,我们最好了解一下他的原理:
这部分知识来源于http://msdn.microsoft.com/zh-cn/library/ms752308.aspx;
http://www.cnblogs.com/zgynhqf/archive/2011/01/24/1942863.html;
http://www.cnblogs.com/gnielee/archive/2010/07/16/wpf-custom-hotkey-command.html;
http://www.cnblogs.com/webabcd/archive/2010/09/13/1824683.html;
命令第一个用途是将语义以及调用命令的对象与执行命令的逻辑分离开来。
这使得多个完全不同的源可以调用相同的命令逻辑,并使得可以针对不同的目标对命令逻辑进行自定义。
例如,在许多应用程序中都能找到的编辑操作“复制”、“剪切”和“粘贴”都可使用不同的用户操作进行调用(如果这些操作是使用命令实现的)。
应用程序可能允许用户通过单击按钮、选择菜单项或使用组合键(例如 Ctrl+X)剪切所选的对象或文本。
通过使用命令,您可以将各种类型的用户操作绑定到同一逻辑。
命令的另一个用途是指示操作是否可用。 仍然以剪切对象或文本作为示例,该操作只有在选择了某些内容时才有意义。
如果用户尝试在没有选择任何内容的情况下剪切对象或文本,则不会发生任何操作。
为了向用户指明这一点,许多应用程序都会禁用按钮和菜单项,以使用户了解是否能够执行某项操作。
WPF 中的路由命令模型可以分为四个主要概念:命令、命令源、命令目标以及命令绑定:
-
命令是要执行的操作。
-
命令源是调用命令的对象。
-
命令目标是在其上执行命令的对象。
-
命令绑定是将命令逻辑映射到命令的对象。
WPF 中的命令是通过实现 ICommand 接口创建的。ICommand 的 WPF 实现是 RoutedCommand 类。
WPF 中的主要输入源是鼠标、键盘、墨迹和路由命令。更加面向设备的输入使用 RoutedEvent 来通知应用程序页中的对象已发生了输入事件。
RoutedCommand 没有不同。RoutedCommand 的 Execute 和 CanExecute 方法不包含命令的应用程序逻辑,
而是引发这样的路由事件:沿元素树以隧道和冒泡形式传递,直到遇到具有 CommandBinding 的对象。
CommandBinding 包含这些事件的处理程序,执行此命令的就是这些处理程序。
CommandBinding 的主要设计目标
是为了在一个较高的逻辑树节点(例如 Window 节点)处,重用固定的命令执行逻辑。
也就是说,当我在 Window上使用 CommandBinding 绑定了某个 RoutedCommand 的执行逻辑后,所有 Window 中的逻辑子结点如果执行了此 RoutedCommand,则会按照路由顺序寻找此 RoutedCommand 所对应的 CommandBinding,找到后,则会执行其绑定的执行逻辑。
这也就是 RoutedCommand 的命名由来,也说明了,CommandBinding 只能用于绑定 RoutedCommand。
WPF Commanding整个命令系统的流程如下:
CommandManager 负责管理路由命令。CommandManager 负责监听一些它关注的属性的更改(例如:Focus、Click),
当界面上有此类事件发生时,它会通知所有的 RoutedCommand 发生 CanExecutedChanged 事件。
这时,已经绑定了这些 RoutedComamnd 的 CommandSource (主要是各类控件),会调用 RoutedCommand 的 CanExecute 方法来检测是否可执行,并根据返回的结果来设置自己的状态。如,当返回可执行时,作为 CommandSource 的按钮则会设置自己的 IsEnabled 属性为 true。此时,如果用户“点击”了这个 CommandSource 时,它会调用它所绑定的 RoutedCommand 的 Execute 方法。
如图所示: