WPF命令
2015-06-28 23:22
423 查看
WPF的命令是经常使用的,在MVVM中,RelayCommand更是用得非常多,但是命令的本质究竟是什么,有了事件为什么还要命令,命令与事件的区别是什么呢?MVVM里面是如何包装命令的呢?命令为什么能够触发呢?带着这些疑问,我们深入讲解下命令:
首先看看命令系统的几个基本元素:
1) 命令(Command):实现了ICommand接口的类,用得最多的是RoutedCommand.
ICommand的成员:
event EventHandler CanExecuteChanged;
bool CanExecute(object parameter);确定此命令能否执行的方法
void Execute(object parameter);执行命令调用的方法
2) 命令源(Command Source):即命令的发送者,是实现了ICommandSource接口的类,很多界面元素都实现了这个接口,其中包括Button, MenuItem, ListBoxItem等。
ICommandSource成员:
ICommand Command{get;} 获取将在调用命令源时执行的命令
object CommandParameter{get; } 命令参数。
IInputElement CommandTarget{get;} 将在其上执行命令的对象。
3)命令目标(Command Target):即命令讲发送给谁,或者说命令将作用在谁身上。命令目标必须是实现了IInputElement接口的类。
4)命令关联(Command Binding):负责把一些外围逻辑与命令关联起来,比如执行之前对命令是否可以执行进行判断、命令执行之后还有哪些后续工作。
CommandBinding的成员:
public ICommand Command{get; set;} 与这个CommandBinding关联的ICommand。
public event CanExecuteRoutedEventHandler CanExecute;
public event ExecutedRoutedEventHandler Executed;
public event CanExecuteRoutedEventHandler PreviewCanExecute;
public event ExecuteRoutedEventHandler PreviewExecuted;
下面先看看一个命令方面的例子:
代码:
View Code
也是点击一个按钮把4个文本框全部清空。
同样的我们来分析下各个要素:
命令:ClearCommand, 实现了ICommand接口,这里的命令执行方法,是执行命令参数的清除方法。
命令源:MyCommandSource,这是一个用户控件,实现了ICommandSource接口,左键按钮里面如果有命令目标,就执行命令方法。
命令目标是一个窗体,他实现了IView接口,接口里面有个清除方法。
这里没有CommandBinding。实际执行的代码就是命令目标的IView接口的方法。
当我们点击按钮的时候,触发了命令的执行,命令执行调用IView接口的方法。
这个自定义的过程要比上面那个例子要好理解一点。
上面的那个例子存在命令源,路由命令和CommandBinding三者之间的关系,命令并不真正执行逻辑代码,是靠CommandBinding来实现逻辑的,当我们真正自定义的命令的时候,如果想简单的使用命令,我们可以把逻辑放到命令里面去,这样便于管理,以上的自定义命令的例子就是这样。
至于MVVM里面的RelayCommand命令,一样也是实现的ICommand接口。当我们把命令通过binding赋值给命令源的Command后,当命令源的命令触发的时候,就执行RelayCommand的方法,这个方法是一个委托方法,这样我们就可以通过Binding来把联系了控件和控件要执行的行为。
命令跟事件可能否是在一起被触发的,比如在ButtonBase的OnClick方法里面是这样的:
protected virtual void OnClick()
{
RoutedEventArgs e = new RoutedEventArgs(ButtonBase.ClickEvent, this);
base.RaiseEvent(e);
CommandHelpers.ExecuteCommandSource(this);
}
可以看出在Click里面,先激发路由事件,再执行命令。
总结:对于命令而言,我们说的几大要素,命令,命令源,命令目标,命令关联,在路由命令中,一般都是存在的,命令在命令源的激发下,到命令目标,有可能没有命令目标,通过命令关联来监控并执行逻辑方面的事情。但是我们一般使用比如MVVM里面的RelayCommand,一般逻辑代码都是放在命令里面的,一般没有命令目标及命令关联。
到目前为止,虽然大致对命令有了个了解,但是对于WPF预定义的一些命令没有完全理解,以及对于命令的好处也没有完全理解,以后随着使用越来越多,再去总结吧。
http://files.cnblogs.com/files/monkeyZhong/RoutedCommandEg.zip
首先看看命令系统的几个基本元素:
1) 命令(Command):实现了ICommand接口的类,用得最多的是RoutedCommand.
ICommand的成员:
event EventHandler CanExecuteChanged;
bool CanExecute(object parameter);确定此命令能否执行的方法
void Execute(object parameter);执行命令调用的方法
2) 命令源(Command Source):即命令的发送者,是实现了ICommandSource接口的类,很多界面元素都实现了这个接口,其中包括Button, MenuItem, ListBoxItem等。
ICommandSource成员:
ICommand Command{get;} 获取将在调用命令源时执行的命令
object CommandParameter{get; } 命令参数。
IInputElement CommandTarget{get;} 将在其上执行命令的对象。
3)命令目标(Command Target):即命令讲发送给谁,或者说命令将作用在谁身上。命令目标必须是实现了IInputElement接口的类。
4)命令关联(Command Binding):负责把一些外围逻辑与命令关联起来,比如执行之前对命令是否可以执行进行判断、命令执行之后还有哪些后续工作。
CommandBinding的成员:
public ICommand Command{get; set;} 与这个CommandBinding关联的ICommand。
public event CanExecuteRoutedEventHandler CanExecute;
public event ExecutedRoutedEventHandler Executed;
public event CanExecuteRoutedEventHandler PreviewCanExecute;
public event ExecuteRoutedEventHandler PreviewExecuted;
下面先看看一个命令方面的例子:
代码:
/// <summary> /// CustomRoutedCommand.xaml 的交互逻辑 /// </summary> public partial class CustomRoutedCommand : UserControl,IView { public CustomRoutedCommand() { InitializeComponent(); } public bool IsChanged { get; set; } public void SetBinding() { } public void Refresh(){} public void Save() { } public void Clear() { this.textBox1.Clear(); this.textBox2.Clear(); this.textBox3.Clear(); this.textBox4.Clear(); } } public interface IView { bool IsChanged { get; set; } void SetBinding(); void Refresh(); void Clear(); void Save(); } public class ClearCommand : ICommand { public bool CanExecute(object parameter) { throw new NotImplementedException(); } public event EventHandler CanExecuteChanged; public void Execute(object parameter) { IView view = parameter as IView; if (view != null) { view.Clear(); } //throw new NotImplementedException(); } } public class MyCommandSource : UserControl, ICommandSource { public ICommand Command { get; set; } public object CommandParameter { get; set; } public IInputElement CommandTarget { get; set; } protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) { base.OnMouseLeftButtonDown(e); if (CommandTarget != null) { this.Command.Execute(CommandTarget); } } }
View Code
也是点击一个按钮把4个文本框全部清空。
同样的我们来分析下各个要素:
命令:ClearCommand, 实现了ICommand接口,这里的命令执行方法,是执行命令参数的清除方法。
命令源:MyCommandSource,这是一个用户控件,实现了ICommandSource接口,左键按钮里面如果有命令目标,就执行命令方法。
命令目标是一个窗体,他实现了IView接口,接口里面有个清除方法。
这里没有CommandBinding。实际执行的代码就是命令目标的IView接口的方法。
当我们点击按钮的时候,触发了命令的执行,命令执行调用IView接口的方法。
这个自定义的过程要比上面那个例子要好理解一点。
上面的那个例子存在命令源,路由命令和CommandBinding三者之间的关系,命令并不真正执行逻辑代码,是靠CommandBinding来实现逻辑的,当我们真正自定义的命令的时候,如果想简单的使用命令,我们可以把逻辑放到命令里面去,这样便于管理,以上的自定义命令的例子就是这样。
至于MVVM里面的RelayCommand命令,一样也是实现的ICommand接口。当我们把命令通过binding赋值给命令源的Command后,当命令源的命令触发的时候,就执行RelayCommand的方法,这个方法是一个委托方法,这样我们就可以通过Binding来把联系了控件和控件要执行的行为。
命令跟事件可能否是在一起被触发的,比如在ButtonBase的OnClick方法里面是这样的:
protected virtual void OnClick()
{
RoutedEventArgs e = new RoutedEventArgs(ButtonBase.ClickEvent, this);
base.RaiseEvent(e);
CommandHelpers.ExecuteCommandSource(this);
}
可以看出在Click里面,先激发路由事件,再执行命令。
总结:对于命令而言,我们说的几大要素,命令,命令源,命令目标,命令关联,在路由命令中,一般都是存在的,命令在命令源的激发下,到命令目标,有可能没有命令目标,通过命令关联来监控并执行逻辑方面的事情。但是我们一般使用比如MVVM里面的RelayCommand,一般逻辑代码都是放在命令里面的,一般没有命令目标及命令关联。
到目前为止,虽然大致对命令有了个了解,但是对于WPF预定义的一些命令没有完全理解,以及对于命令的好处也没有完全理解,以后随着使用越来越多,再去总结吧。
http://files.cnblogs.com/files/monkeyZhong/RoutedCommandEg.zip
相关文章推荐
- 第一个servlet程序
- WPF listview 隐藏Header 列头
- 读取某个文件夹下的所有文件
- 22.AndroidManifest中original-package标签
- CALayer-简介(一)
- 博客园地址
- 【Java.Core】Enum
- 笔记--《谷歌和亚马逊是怎么做产品的》第一至三章
- Android编程之SparseArray<E>详解
- LeetCode All in One 题目讲解汇总(持续更新中...)
- linux下/dev/shm是什么
- constraint 摘自群主大大
- 2015年6月28日 课设日志
- 关于 android 中 postDelayed方法的讲解
- PHP接入umeditor(百度富文本编辑器)
- Node.js学习-----------异步文件读取
- linux char device driver and ioctl 0629
- Http协议和web本职【转自丁码农】
- 20.在美丽的店 店铺端开发中, baseActivity采用了frame布局,id为fram_content的用于存放子Activity中的布局.但如果frame.xml如下所示, 会出现中间部分为
- 视觉平台搭建——LED光源介绍