1.概念

对于程序来说,命令就是一个个任务,例如保存,复制,剪切这些操作都可以理解为一个个命令。即当我们点击一个复杂按钮时,此时就相当于发出了一个复制的命令,即告诉文本框执行一个复杂选中内容的操作,然后由文本框控件去完成复制的操作。在这里,复杂按钮就相当于一个命令发送者,而文本框就是命令的执行者。它们之间通过命令对象分割开了。如果采用事件处理机制的话,此时调用程序与处理程序就相互引用了。

  所以对于命令只是从不同角度理解问题的一个词汇,之前理解点击一个按钮,触发了一个点击事件,在WPF编程中也可以理解为触发了一个命令。说到这里,问题又来了,WPF中既然有了命令了?那为什么还需要路由事件呢?对于这个问题,我的理解是,事件和命令是处理问题的两种方式,它们之间根本不存在冲突的,并且WPF命令中使用了路由事件。所以准确地说WPF命令应该是路由命令。那为什么说WPF命令是路由的呢?这个疑惑将会在WPF命令模型介绍中为大家解答。

  另外,WPF命令除了使命令源和命令目标分割的优点外,它还具有另一个优点:

使得控件的启用状态和相应的命令状态保持同步,即命令被禁用时,此时绑定命令的控件也会被禁用。

2.命令模型

WPF命令模型具有4个重要元素:

命令——命令表示一个程序任务,并且可跟踪该任务是否能被执行。然而,命令实际上不包含执行应用程序的代码,真正处理程序在命令目标中。
命令源——命令源触发命令,即命令的发送者。例如Button、MenuItem等控件都是命令源,单击它们都会执行绑定的命令。
命令目标——命令目标是在其中执行命令的元素。如Copy命令可以在TextBox控件中复制文本。
命令绑定——前面说过,命令是不包含执行程序的代码的,真正处理程序存在于命令目标中。那命令是怎样映射到处理程序中的呢?这个过程就是通过命令绑定来完成的,命令绑定完成的就是红娘牵线的作用。
  WPF命令模型的核心就在于ICommand接口了,该接口定义命令的工作原理。该接口的定义如下所示:

public interface ICommand
{
// Events
event EventHandler CanExecuteChanged; // Methods
bool CanExecute(object parameter); void Execute(object parameter);
}
public class MyClass
{
//委托命令
public DelegateCommand DC_Command { get; set; }
public void Fun_MyFunction(object sender)
{
Task.Run(() =>
{
this.LoadingShow();
Application.Current.Dispatcher.Invoke(new Action(() =>
{
//do something
}));
this.LoadingHide();
});
} public MyClass()
{
this.DC_Command = new DelegateCommand(new Action<object>(this.Fun_MyFunction));
}
}
<Button Margin="10" Padding="5" Command="{Binding DC_Command}">Click</Button>
public class DelegateCommand : ICommand
{
private Action<object> executeAction;
private Func<object, bool> canExecuteFunc;
public event EventHandler CanExecuteChanged; public DelegateCommand(Action<object> execute)
: this(execute, null)
{ } public DelegateCommand(Action<object> execute, Func<object, bool> canExecute)
{
if (execute == null)
{
return;
}
executeAction = execute;
canExecuteFunc = canExecute;
} public bool CanExecute(object parameter)
{
if (canExecuteFunc == null)
{
return true;
}
return canExecuteFunc(parameter);
} public void Execute(object parameter)
{
if (executeAction == null)
{
return;
}
executeAction(parameter);
}
}

最新文章

  1. Android开发之Activity横竖屏切换生命周期重建问题
  2. python调用其他程序或脚本方法(转)
  3. Maximal Square || LeetCode
  4. c++中的类的对象与类的指针
  5. UCOS-互斥信号量(学习笔记)
  6. 玩耍Hibernate之缓存
  7. 8个必备的PHP功能开发 (转)
  8. array_multisort 关联(string)键名保持不变,但数字键名会被重新索引。
  9. bzoj1180,2843
  10. N维法向量与N维超平面的关系的简单证明(日志二)
  11. BookNote: Refactoring - Improving the Design of Existing Code
  12. python爬虫 - python requests网络请求简洁之道
  13. 重构:以Java POI 导出EXCEL为例
  14. Python Scrapy反爬虫常见解决方案(包含5种方法)
  15. LeetCode 解题总结
  16. mongoose之操作mongoDB数据库
  17. Vue基础进阶 之 常用的实例属性
  18. IO流小笔记
  19. Python cmd中输入&#39;pip&#39; 不是内部或外部命令,也不是可运行的程序或批处理文件。
  20. ASP防止SQL注入

热门文章

  1. 聊聊SNMP协议
  2. C#排序算法的实现---冒泡排序
  3. javaweb 使用页面模板CSS或者Js修改失效的解决办法(Tomcat缓存问题)
  4. cin,cin.get(),cin.getline(),gets(),getchar()函数的用法
  5. Luogu2345 | 奶牛集会 (树状数组)
  6. python之路(内存,小数据池,编码等)
  7. Beamer加入背景图片
  8. 工作问题--------爬虫遇到requests.exceptions.ConnectionError: HTTPSConnectionPool Max retries exceeded
  9. 深入理解IP之CIDR
  10. 微信小程序CSS之Flex布局