WPF命令模型

WPF命令模型的组成

 

WPF命令模型可有许多可变的部分组成,总之,他们都具有如下4个重要元素:

(1)命令,命令表示应用程序任务,并且跟踪任务是否能够被执行,然而,命令实际上不包含执行应用程序任务的代码

(2)命令绑定,每个命令绑定针对用户界面的具体区域,将命令连接到相关的应用程序逻辑,这种分解的设计是非常重要的,因为单个命令可用于应用程序的多个地方,并且在每个地方具有不同的意义,为处理这一问题,需要将同一命令与不同命令绑定

(3)命令源,命令源触发命令,例如MenuItem和Button都是命令源,单击他们都会执行绑定命令

(4)命令目标,命令目标是在其中执行命令的元素,例如,Paste命令可在TextBox控件中插入文本,而OpenFile命令可在DocumentViewer中打开文档,根据命令的本质,目标可能很重要,也可能不重要.

 

ICommand接口

 

WPF命令模型的核心是System.Windows.Input.ICommand接口,该接口定义了命令工作原理,该接口包含两个方法和一个事件

public interface ICommand
{
	void Execute(object parameter);
	bool CanExecute(object parameter);

	event EventHandle CanExecuteChanged;
}

 

在一个简单实现中,execute()方法将包含应用程序任务逻辑.然而,WPF实现复杂,他使用execute()方法引发了一个更复杂的过程,该过程最终触发在应用程序其他地方处理事件,通过这种方式可以使用预先准备好的命令类,并插入自己的逻辑,还可以灵活的在几个不同的地方使用同一个命令.

 

canexecute()方法返回命令的状态,如果命令可用返回true,否则返回false,execute()和canexecute()方法都接受一个附加的参数对象,可使用该对象传递所需的任何附加信息

 

最后当命令状态改变时引发,canexecutechanged()事件,对于使用命令的任何控件,这是指示信号,标识他们应当调用canexecute()方法检查命令的状态,通过使用该事件,当命令可用时,命令源可自动启用自身,当命令不可用时,禁用自身.

 

RoutedCommand类

 

当创建自己的命令时,不会直接实现ICommand接口,而是使用System.Windows.Input.RoutedComand类,该类自动实现了ICommand接口,RoutedCommand类是WPF中唯一实现了ICommand接口的类,换句话说,所有WPF命令都是RoutedCommand类及派生类的实例.

 

在WPF命令模型背后的一个重要概念是,RoutedCommand类不包含任何应用程序逻辑,而只代表命令,这以为着各个RoutedComand对象具有相同的功能.

RoutedCommand类为事件冒泡和隧道添加了一些额外的基础结构,鉴于IComand接口封装了命令的思想,可被触发的动作并可被启用或禁用–RoutedCommand类对命令进行了修改,使命令可在WPF元素层次结构中冒泡,以便获得正确的事件处理程序.

 

为支持路由事件,RoutedCommand类私有的实现了IComand接口,并添加了IComand接口方法的一些不同版本,最明显的变化是,execute()和canexecute()方法使用了一个额外参数,下面是新的签名

 

public void Execute(object parameter,IInputElement target){…}

public void CanExecute(object parameter,IInputElement target){…}

 

参数target是开始处理事件的元素,事件从target元素开始,然后冒泡至高层的容器直到应用程序为了执行合适的任务而处理了事件(为了处理Executed事件,元素还需要借助另一个类–CommandBinding类的帮助)

 

除上面的修改外,RoutedComand类还引入了三个属性,命令名称,包含命令的类以及任何可用于触发命令的按键或鼠标操作

 

RoutedUICommand类

 

在程序处理的大部分命令不是RoutedCommand对象,而是RoutedUICommand类的实例,RoutedUICommand类继承自RoutedComand类(实际上,WPF提供的所有预先构建好的命令都是RoutedUIComand对象)

 

RoutedUICommand类用于具有文本的命令,这些文本显示在用户界面的某些地方,RoutedUICommand类只增加了Text属性,该属性是为命令显示的文本.

 

为命令定义命令文本(而不是直接在控件上定义文本)的优点是可在某个位置执行本地话,但如果命令文本永远不会在用户界面的任何地方显示,那么RoutedUIComand类和RoutedCommand类是等效的.