WPF中的命令与命令绑定(二)
WPF中的命令与命令绑定(二)
周银辉
在WPF中,命令(Commanding)被分割成了四个部分,分别是ICommand,ICommandSource,CommandTarget和CommandBinding。下面我们来分别探讨这四个部分。
1,ICommand
Command也就是我们的“命令”本身,比如“复制”“粘贴”。在WPF中,所有的命令都必须实现ICommand接口,它为所有的命令提供一个抽象,这个抽象对于我们实现Undo、Redo操作非常重要,如果你学习一下设计模式中的“命令”模式,你会更加深刻的理解。
ICommand接口中拥有Execute()方法,该方法用于命令的执行(不过,注意:命令的执行逻辑——比如将剪切板中的文本去出来放到文本框的合适位置——并没有被编写到该方法中,稍后我们会讲到这其中的奥妙),另外的一个方法是CanExecute()用于指示当前命令在目标元素上是否可用,当这种可用性发生改变时其便会引发该接口的尾页一个事件CanExecuteChanged。
在目前的WPF类库中,你能看到唯一一个实现了ICommand接口的类型RoutedCommand(其实还有一个名为SecureUICommand的类也实现了该接口,不过该类未被公开),“Routed”是一个不太容易被翻译的修饰词(有人将它翻译为“路由”),但这意味着该类型的命令可以向WPF中的RoutedEvent一样在元素树中上下传递。
RoutedCommand的子类RoutedUICommand是我们经常使用的类型,它与RoutedCommand的不同之处仅仅在与它多了一个Text属性来描述该命令,不过大多数WPF内置命令的Text属性有一个很不错的特点:其支持自动本地化。这至少会为我们的软件的本地化减少工作量。
在本系列随笔的后续部分将介绍如何自定义一个命令。
2,ICommandSource与CommandTarget
命令源,用来触发我们的命令,比如用一个菜单项来触发“复制”命令,那么该菜单项就是命令源。要使一个元素成为命令源,其必须实现ICommandSource接口。命令源决定了它所要触发的命令、该命令所作用的对象以及命令参数(如果需要的话),这分别对应于它的三个属性:Command、CommandTarget以及CommandParameter。其中需要注意的是CommandTarget,因为在WPF中如果你不为命令源指定其命令对象,那么其将会把界面上获得键盘焦点的元素作为默认的命令对象,这为我们提供了方便,比如界面上有两个文本框,我们不必担心主菜单项上的“粘贴”操作是针对哪个文本框的,谁获得焦点便针对谁,这符合大家的习惯。但引入的问题是,如果命令目标不具备获取键盘焦点的能力(比如Label)或命令源会抢占焦点(比如用Button来代替菜单项,点击按钮时焦点由文本框转移到了按钮上),你的命令将会无效,这时你就必须为命令源指定命令目标。
在本系列随笔的后续部分将介绍如何让你的自定义控件成为命令源和命令目标。
3,CommandBinding
前面已经提到我们并没有将命令的执行逻辑编写到其Excute()方法中,这是有道理的,比如"粘贴"命令(ApplicationCommands.Paste),粘贴一段文本到文本框和粘贴一个图片到绘图板的执行逻辑肯定是不一样的,负责开发该“粘贴”命令的开发人员不可能知道所有的粘贴操作的具体逻辑,使用“粘贴”命令的客户也不应该为该执行逻辑负责,编写该执行逻辑的任务应该被分发给那些支持“粘贴”操作的控件的开发人员以及那些希望为自己的控件添加“粘贴”操作的客户。也就是说我们需要将“行为的请求者(命令)”和“行为的执行者(命令的执行逻辑)”分开而实现一种松耦合,而CommandBinding(命令绑定)便是命令和命令执行逻辑的桥接器。
我们使用CommandBinding将命令与其合适的执行逻辑绑定在一起:


CommandBinding构造方法的最后两个参数分别是ExecutedRoutedEventHandler 与 CanExecuteRoutedEventHandler 类型的委托,用于指示如何执行命令和如何判断命令能否被执行。
与CommandBinding一样扮演着中间角色的还有CommandManager类,它为命令绑定(以及输入绑定)提供了很多实用方法。
在本系列随笔的后续部分将介绍WPF的命令系统与“命令模式”(设计模式之一)之间的关系。
WPF中的命令与命令绑定(二)的更多相关文章
- 在WPF中自定义你的绘制(二)
原文:在WPF中自定义你的绘制(二) 在WPF中自定义你的绘制(二) ...
- WPF中的多进程(Threading)处理实例(二)
原文:WPF中的多进程(Threading)处理实例(二) //错误的处理 private void cmdBreakRules_Click(object sender, RoutedEventArg ...
- WPF中PasswordBox控件无法绑定Password属性解决办法
在WPF中,默认的Password控件的Password属性是不允许为之绑定的,下面是一个解决绑定Password的方法的代码: 1.前台代码 <Window x:Class="Pas ...
- wpf中UserControl的几种绑定方式
我们经常会抽取一些可重用的控件,某个属性是否需要重用,直接决定了这个属性的绑定方式. 1.完全不可重用的控件 有一些与业务强相关的控件,它们的属性完全来自ViewModel,越是相对复杂的控件,越容易 ...
- WPF中,多key值绑定问题,一个key绑定一个界面上的对象
问题说明: 当用到dictionary<key,value>来储存数据的时候,有时候需要在界面上绑定一个key来显示value,这时候有两种思路: 一种是写一个自定义的扩展类,类似Bind ...
- WPF学习笔记四之命令
1.概念 对于程序来说,命令就是一个个任务,例如保存,复制,剪切这些操作都可以理解为一个个命令.即当我们点击一个复杂按钮时,此时就相当于发出了一个复制的命令,即告诉文本框执行一个复杂选中内容的操作,然 ...
- 二维图形的矩阵变换(二)——WPF中的矩阵变换基础
原文:二维图形的矩阵变换(二)--WPF中的矩阵变换基础 在前文二维图形的矩阵变换(一)——基本概念中已经介绍过二维图像矩阵变换的一些基础知识,本文中主要介绍一下如何在WPF中进行矩阵变换. Matr ...
- WPF中在MVVM模式下,后台绑定ListCollectionView事件触发问题
问题:WPF中MVVM模式下 ListView绑定ListCollectionView时,CurrentChanged无法触发 解决方案: 初期方案:利用ListView的SelectionChang ...
- 在WPF中UserControl
在这里我们将将打造一个UserControl(用户控件)来逐步讲解如何在WPF中自定义控件,并将WPF的一些新特性引入到自定义控件中来.我们制作了一个带语音报时功能的钟表控件, 效果如下: 在VS中右 ...
随机推荐
- nodejs理解
一.nodejs介绍 nodejs主要体现在事件机制和异步IO,nodejs是事件驱动的: nodejs作用:js的运行环境.操作文件.链接数据库: nodejs在执行js是单线程的,但不是nodej ...
- Android(java)学习笔记7:多线程程序练习
需求: 某电影院目前正在上映贺岁大片,共有100张票,而它有3个售票窗口售票,请设计一个程序模拟该电影院售票. 两种方式实现 A:继承Thread类 B:实现Runnable接 1. 首先我们利用方式 ...
- bzoj5029 贴小广告
Description 现在有一堵墙,墙上分为若干个单元.接下来会来n个人在墙上贴小广告.每次每个人选择墙上连续一段的单元贴上自己公司与众不同的小广告.因为小广告可能会出现被覆盖的情况,由于公司之间存 ...
- C++设计模式实现--訪问者(Visitor)模式
版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/L_Andy/article/details/36896645 一. 訪问者模式 定义:表示一个作用于 ...
- python nmap模块使用进行主机探测(ICMP)
终于审核通过了......第一次用博客,想记录自己的学习情况,分享知识. 废话不多说,第一篇blog,大牛请轻喷. 资产清点首先需要进行主机探测,将存活主机统计下来再进行进一步的指纹识别及端口探测.若 ...
- 2018.9.17 面试问题-----如何对List集合中的元素进行排序?
Collections对List集合中的数据进行排序 有时候需要对集合中的元素按照一定的规则进行排序,这就需要用到 Java中提供的对集合进行操作的工具类Collections,其中的sort方法 先 ...
- php 的 number_format使用
$num = 1.0258963147; // 1.0259 $num = number_format($num, 4, '.', ''); $num = number_format($num); $ ...
- FastJSON、Gson、Jackson(简单了解使用)
下载地址(maven) Jackson:http://mvnrepository.com/search?q=jackson FastJson:http://mvnrepository.com/sear ...
- 史上最简单的 SpringCloud 教程 | 第一篇: 服务的注册与发现Eureka(Finchley版本)
转载请标明出处: 原文首发于:https://www.fangzhipeng.com/springcloud/2018/08/30/sc-f1-eureka/ 本文出自方志朋的博客 一.spring ...
- 插入排序_C语言_数组
插入排序_C语言_数组 #include <stdio.h> void insertSort(int *); int main(int argc, const char * argv[]) ...