继续聊WPF——自定义命令

摘要:
思考完之后,让我们谈谈WPF中的命令。接下来,让我们完成一个示例:1.创建一个新的WPF应用程序。如何创建它--添加命令绑定--˃<Grid><Grid。行定义˃<RowDefinition/><RowDefinition/˃在上面的XAML中,我们应该注意,引入定义路由命令的类的命名空间。接下来,我们需要编写两个事件处理程序-CanExecute来确定命令是否可用;执行命令的逻辑应该写在这里。ExecutedRoutedEventArgs的Source属性是命令目标。
作为春节前的最后一篇技术文章,写点什么呢?想了一下,就聊聊WPF中的命令吧。
命令这东西很有意思,简明一点说,它是一种逻辑,但这种逻辑可以被多种源调用,可以作用于多种目标上。如我们常见的“复制”,“剪切”等命令,它们本身就是一种逻辑——对剪切板进行操作的逻辑行为,不过,你会发现,它们不仅可以在菜单项中使用,也可以在工具栏按钮上使用,也可以通过快捷键Ctrl + C等来调用。

菜单项

继续聊WPF——自定义命令第1张
工具栏按钮
继续聊WPF——自定义命令第2张

从上面的举例可以发现,命令可以使用具备相同功能的代码逻辑变得通用化,就像我们封装了一个类一样,可以在N个地方进行调用,这样我们不必每次都写相同的代码。

.NET类库已为我们准备了许多通用命令,使用起来也很简单,这里就不说了,大家可以参考MSDN上相关说明,本文的主题是自定义命令,在讲述自定义命令之前,先了解一下与命令有关的几个要素,就像我们常说的“记叙文六要素”一样,一个完整的命令应当包括:

1、命令,这当然是核心部分了;

2、命令源:命令是谁发出的;

3、目标,命令作用在哪些元素上,如往文本框中粘贴内容,那么该TextBox就是命令目标;

严格上说,命令是实现了ICommand接口的类,但是,在际使用中,我们不必这样做,一种有效的方法是在某个类中直接声明一个RouteCommand类的成员字段即可,一般使用Static关键字,这样可以使得命令只与类有关,而不必理会其属于哪个实例。

下面,我们一起动手完成一个实例:

1、新建一个WPF应用程序,如何新建?(略);

2、布局好主窗体,我们重点是需要两个文本框和一个按钮,其它的自己喜欢;

3、使用CommadBinding把命令添加到窗体类的CommandBindings集合中。

4、在按钮上设置Command属性。


在上面的XAML中,我们要注意的是,要引入我们定义了路由命令的类所在的命名空间。
接下来,我们要编写两个事件处理程序——CanExecute确定命令是否可用;Executed命令逻辑应写在这里。

这样我们会有一个疑问,事件的引发者是谁?命令目标又是谁?

我们在Executed事件处理程序的开始处下一个断点,然后单步跟入。

继续聊WPF——自定义命令第3张

得到的结果如下:

sender是主窗体。

继续聊WPF——自定义命令第4张

ExecutedRoutedEventArgs的Source属性就是命令目标。

继续聊WPF——自定义命令第5张

但是,当我们运行的时候,我们发现字体变成蓝色的并不是文本框,而是按钮,为什呢?

我们仔细阅读一下MSDN文档及相关说明就知道了,因为我们没有设置Target,所以,默认的是当前获得焦点的元素将成为命令目标。

下面我们改一个上面的XAML让Button的CommandTarget指向第二个文本框。


现在运行一下,可以发现,点击按钮后,第二个文本框的前景色就变成蓝色了。

继续聊WPF——自定义命令第6张

CanExecute事件和Executed事件都是路由事件,当然,RouteCommand类也包含遂道事件,至于什么是路由事件,什么是遂道事件,不在本文讲述的范围之中。

以路由事件为例,下面我们来做第二个示例。这个示例,窗体上有一个StackPanel,里面包含一个按钮,同时,把CommandBinding添加到该StackPanel上,而该StackPanel里面再嵌套一个DockPanel,同样,把同一个命令也添加到DockPanel上,DockPanel里面再包含一个Canvas,但是Canvas不添加CommandBinding,然后,在Executed事件处理程序中分别输出引发事件的类型,命令目标类型和目标的Name属性的值。

[XAML]


[C# Code]


然后,我们运行程序,依次点击这三个按钮,接着打开“输出”窗口观察一下。

得到的结果如下:


发现了什么?从调试信息中看到,后两次执行命令,引发事件的类型都是DockPanel,这也符合路由事件沿可视化树往上冒泡的原则了。

因为Canvas中我们没有绑定命令,所以在Canvas上无法引发事件,于是,向上路由到DockPanel,所以后两次事件的触发者都是DockPanel。

接下来,我们还要动手做第三个示例,示例不通过控件来执行命令,而是通过快捷键Ctrl + Alt + Y来激活。


运行程序,当窗口处于活动状态,然后按下Ctrl + Alt + Y,你就看到效果了。

免责声明:文章转载自《继续聊WPF——自定义命令》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇C#中Bitmap类 对图像の操作 可检测图片完整性[转自小兵的工具箱]C++ Builder 基础下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

WPF MVVM实现ListBox添加不同的控件

和之前一样,新建一个WPF工程,Models,Views,ViewModels文件夹,另外添加Selector文件夹。 第一,Selector文件夹中添加TemplateSelectorDemo类 public class TemplateSelectorDemo: DataTemplateSelector { public...

WPF 事件快速参考

为了提供快速参考,下面列出了 Expression Blend 中的可用事件。可用的事件可能会随着用户在“交互”面板的“对象和时间线”下选定不同的对象而有所变化。例如,如果在“对象和时间线”下选定“LayoutRoot”对象,则无法创建“Activated”事件处理程序方法,因为该事件仅对“Window”对象有效。 事件 描述 Annotatio...

wpf prism加载独立模块实例

一、首先看看文件的组织架构 module1 module2生成dll某块。Shell来显示管理模块 二,看看关键bootstrapper类 using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threading.Tas...

WPF MVVM模式

什么是MVVM模式,Model(模型)-View(视图)-ViewModel(视图模型) 先来讲MVC模式,模型-视图-控制器,相信大多数人都用过原理无非是: 页面产生某个请求,先找到页面对应的控制器,然后触发控制器的方法,控制器去模型调取数据拿回来,再返回给相应的视图,最后呈现页面。 MVVM模式原理类似MVC,只不过中间的不叫控制器了叫视图模型,功能也...

WPF 2D绘图(2)Geometry

Shape是对Geometry的一种封装,Shape本质上还是通过绘制Geometry的形状,然后以填充笔刷来呈现效果 如Rectangle <Path Stroke="Black" StrokeThickness="1" Fill="#CCCCFF"> <Path.Data>...

Modern UI for WPF 开源项目(2):我的第一个Modern UI App

1.获取最新版本的modern UI for WPF 2.打开vs并创建一个新的WPF应用程序名为:MuiTest 3.添加FirstFloor.ModernUI.dll 4.定义ModernWindow继承于MainWindow 打开MainWindows.xaml,添加ModernUI 的 xmlns 名称空间和使用mui来替换Window标签,如下:...