简单理解,深入浅出话命令

作者: 单机闯关小游戏  发布:2019-08-30

命令(Command)

转自:

WPF为大家准备了健全的授命系统,你可能会问:“有了路由事件为何还索要命令系统啊?”。事件的效果是发表、传播一些新闻,音信传达到了收信人,事件的命令也纵然完毕了,至于何以响应事件送来的消息事件并不做别的限制,每一个接收者可已用本身的一言一行来响应事件。也正是说,事件不抱有约束力。命令和事件的界别就在于命令具备约束力。

真正,在其实编制程序专门的学问中,固然只用事件不要命令程序的逻辑一样被驱动的很好,但大家不可知堵住程序猿根据本人的习贯去编写代码。比如保留事件的微管理器,技术员能够写Save()、SaveHandle()、SaveDocument()... 那个都符合代码标准。但迟早有一天整个项目会变的令人无可奈何读懂,新来的技师或修改bug的技术员会很抓狂。假使利用命令,情形就能够好过多----当Save命令达到某些组件的时候,命令会活动去调用组件的Save方法。而以此格局恐怕定义在基类只怕接口里(即确定保证了那一个方法是一定期存款在的),那就在代码结商谈命名上做了封锁。不但如此,命令还可决定接收者“先做校验,再保存,最终退出”,也正是说命令除了能够约束代码,还足以约束步骤逻辑,让新来的程序猿想犯错都难,也让老大修改Bug的程序员轻松找到规律,轻易上手。

1.1      命令系统的着力要素和事关

 

  • WPF的通令系统由多少个基本要素构成,它们是:
  • 指令(Command):WPF的命令实际上正是兑现了ICommand接口的类,平时利用最多的正是RoutedCommand类。大家还可能会学习应用自定义命令。
  • 命令源(Command Source):即命令的发送者,是贯彻了ICommandSource接口的类。很多分界面成分都落到实处了这么些接口,在那之中满含Button,ListBoxItem,MenuItem等。
  • 一声令下目的(Command Target):即命令发送给什么人,或然说命令功效在哪个人的身上。命令目的必需是完结了IInputElement接口的类。
  • 一声令下关联(Command Binding):担当把一部卓殊部逻辑和指令关联起来,举个例子实施以前对命令是不是能够实行实行剖断、命令实施之后还应该有怎么着后续职业等。

1.2      基本因素之间的关联

那么些基本成分的涉及彰显在使用命令的进程中。命令的应用大致分为以下几步:

(1)成立命令类:即得到叁个贯彻ICommand接口的类,如若命令与具象的作业逻辑毫不相关则使用WPF类库中的(RoutedCommand)类就能够。如果想赢得与作业逻辑相关的专有命令,则要求创设RoutedCommand(只怕ICommand接口)的派生类。

(2)注脚命名实例:使用命令时须要创设命令类的实例。这里有多少个技术,一般景观下程序中某种操作只供给叁个指令实例与之对应就能够。举个例子对应“保存”那些命令操作。因而前后相继中的命令多选用单件方式以减掉代码的复杂度。

(3)钦点命令的源:即钦点由何人来发送命令。假设把命令看作炮弹,那么命令源就一定于火炮。同二个命令能够有四个源。比方保留命令,即能够由菜单中的保存项来发送,也得以由保存工具栏中的Logo举办发送。须求专一的是,一旦把命令指派给了命令源,那么命令源就能够受命令的熏陶,当命令不可能被试行的时候命令源的控件处于不可用状态。看来命令这种炮弹还很智能,当不满意发送条件的时候还只怕会给用来发出它的火炮上一道有限扶助、制止走火。还亟需留心,各类控件发送命令的方法不经同样,举例Button和MenuButton在单击时发送命令,而ListBoxItem单击时表示被入选,双击的时候才发送命令。

(4)指令命令目的:命令目的并非命令的习性,而是命令源的脾气。钦命命令指标是报告命令源向哪个组件发送命令。无论这么些组件是不是具备宗旨他都会接到这些命令。若无为源内定命令目的,则WPF系统认为眼下持有宗旨的目的就是命令目的。这些手续有一点像为火炮钦赐指标。

(5)设置命令关联:炮兵是无法独立大战的,就如炮兵在安顿以前须要武警旁观敌情、推断发射机遇,在发射后观察射击效果,帮助改进同样。WPF命令必要CommandBinding在实行从前来增加帮衬鉴定是或不是足以实践、在实践后做一些事来“打扫战地”。

在命令目的和下令关联之间还应该有一对微妙的涉嫌。无论命令指标是由程序猿钦命依然由WPF系统依据难题所在地剖断出来的,一旦有个别UI组件被命令源瞄上,命令源就能够持续的向命令指标投砾引珠,命令指标就能够不停的出殡可路由的PreviewCanExecute和CanExecute附加事件。事件会沿UI成分树向上传递并被命令关联所抓获,命令关联会达成都部队分后续任务。别小看“后续职责”,对于那三个事情逻辑无关的通用命令,这几个后续职分才是最要害的。

您可能会问:“命令目的怎会发出PreviewCanExecute、CanExecute、PreviewExecute和Executed事件吧?”其实那4个事件都是外加事件,是被CommandManager类“附加”给命令目的的。大家能够翻过头来再领会一下叠合事件。另外,PreviewCanExecute和CanExecute的实行机遇不由技士调控,並且试行功用比较高,那不仅仅给系统特性带来了些减弱,不常还恐怕会引进多少个想不到的BUG何况比较难调节和测试,请我们必须多加小心。

下图所示是WPF命令系统焦点要素的涉及图:

图片 1

1.3         小规模试制命令

聊起来很繁华,现在让我们开始奉行一下。完毕如此三个供给:定义贰个限令,使用Button来发送那几个命令,当命令达到Text博克斯的时候,TextBox会被清空(假使TextBox未有文字,命令不可用。)。

程序XAML代码如下:

[html] view plaincopy简单理解,深入浅出话命令。print?

 

 

  1. <Window x:Class="WpfApplication1.Window28"  
  2.         xmlns=""  
  3. 简单理解,深入浅出话命令。        xmlns:x=""  
  4.         Title="Window28" Height="300" Width="300" WindowStyle="ToolWindow">  
  5.     <StackPanel Background="LightBlue" x:Name="sp1">  
  6.         <Button Content="Send Command" x:Name="btn1" Margin="5"></Button>  
  7.         <TextBox x:Name="txtA" Margin="5,0" Height="200"></TextBox>  
  8.     </StackPanel>  
  9. </Window>  

后台代码为:

[简单理解,深入浅出话命令。csharp] view plaincopyprint?

 

 

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Text;  
  5. using System.Windows;  
  6. using System.Windows.Controls;  
  7. using System.Windows.Data;  
  8. using System.Windows.Documents;  
  9. using System.Windows.Input;  
  10. using System.Windows.Media;  
  11. using System.Windows.Media.Imaging;  
  12. using System.Windows.Shapes;  
  13.   
  14. namespace WpfApplication1  
  15. {  
  16.     /// <summary>  
  17.     /// Window28.xaml 的互动逻辑  
  18.     /// </summary>  
  19.     public partial class Window28 : Window  
  20.     {  
  21.         public Window28()  
  22.         {  
  23.             InitializeComponent();  
  24.             InitializeCommand();  
  25.         }  
  26.         //注脚并定义命令  
  27.         private RoutedCommand rouutedCommand = new RoutedCommand("Clear",typeof(Window28));  
  28.         private void InitializeCommand()  
  29.         {  
  30. 简单理解,深入浅出话命令。            //把命令赋值给命令源,并定义快捷键  
  31.             this.btn1.Command = rouutedCommand;  
  32.             this.rouutedCommand.InputGestures.Add(new KeyGesture(Key.C, ModifierKeys.Alt));  
  33.             //内定命令指标  
  34.             this.btn1.CommandTarget = txtA;  
  35.   
  36.             //成立命令关联  
  37.             CommandBinding commandBinding = new CommandBinding();  
  38.             commandBinding.Command = rouutedCommand;//只关注与rouutedCommand相关的通令  
  39.             commandBinding.CanExecute  = new CanExecuteRoutedEventHandler(cb_CanExecute);  
  40.             commandBinding.Executed  = new ExecutedRoutedEventHandler(cb_Execute);  
  41.             //把命令关联安置在外面控件上  
  42.             this.sp1.CommandBindings.Add(commandBinding);  
  43.         }  
  44.         //当命令达到指标之后,此办法被调用  
  45. 简单理解,深入浅出话命令。        private void cb_Execute(object sender, ExecutedRoutedEventArgs e)  
  46.         {  
  47.             txtA.Clear();  
  48.             //防止事件持续发展传递而裁减程序品质  
  49.             e.Handled = true;  
  50.         }  
  51.         //当探测命令是或不是可实践的时候该格局会被调用  
  52.         private void cb_CanExecute(object sender,CanExecuteRoutedEventArgs e)  
  53.         {  
  54.             if (string.IsNullOrEmpty(txtA.Text))  
  55.             {  
  56.                 e.CanExecute = false;  
  57.             }  
  58.             else  
  59.             {  
  60.                 e.CanExecute = true;  
  61.             }  
  62.             //防止事件后续发展传递而减低程序品质  
  63.             e.Handled = true;  
  64.         }  
  65.   
  66.     }  
  67. 简单理解,深入浅出话命令。}  

简单理解,深入浅出话命令。运营程序,在TextBox中输入内容之后,Button在指令可实行情形下成为可用,此时单击按键或许按Alt C,TextBox就能够被清空,效果如下图:

图片 2                                                图片 3

对此以上的代码,须要注意以下几点:

先是,使用命令能够制止本身写代码推断Button是或不是可以用以及增多赶快键。

其次,RountedCommand是三个与职业逻辑毫无干系的类,只担任在前后相继中跑腿而并不对命令目标张开操作,TextBox并非由它清空的。那么TextBox的情景操作是哪个人啊?答案是CommandBinding。因为随意探测命令是或不是能够实行也许命令送达目的,都会激起命令目的发送路由事件,这一个事件会顺着UI成分树向上传递,最终被CommandBinding所捕捉。本例中CommandBinding棉被服装置在外面包车型大巴StackPanel上,Commandbinding站在高处起三个侦听器的作用,并且特别针对rouutedCommand命令捕捉与其连带的风浪。本例中,当CommandBinding捕捉到CanExecute就能调用cb_CanExecute方法。当捕捉到是Executed的时候,就调用cb_Execute事件。

其三,因为CanExecute事件的振奋频率相比高,为了幸免减弱质量,在管理达成之后建议将e.Handle设置为true。

第四,CommandBinding一定要安装在命令指标的外场控件上,不然不能够捕捉CanExecute和Executed等路由事件。

1.4         WPF中的命令库

上面那一个例子中,大家和好表明定义了三个命令:

[csharp] view plaincopyprint?

 

 

  1. private RoutedCommand rouutedCommand = new RoutedCommand("Clear",typeof(Window28));  

一声令下具有一处评释,四处使用的特征,比方Save命令,在前后相继的别的地点它都表示供给命令指标保存数据。由此,微软在WPF类库里面筹划了一部分轻松的命令库,那么些命令库富含:

ApplicationCommands

ComponentCommands

简单理解,深入浅出话命令。NavigationCommands

MediaCommands

EditingCommands

它们都以静态类,而下令正是由那个静态类的只读属性以单件情势暴表露来的。比如:ApplicationCommands类就带有CancelPrint、Close、ContextMenu、Copy、CorrectionList、Cut、Delete、Find、Help、New、NotACommand、Open、Paste、Print、PrintPreview、Properties、Redo、Replace、Save、SaveAs、SelectAll、Stop、Undo那些命令。它们的源代码如下:

图片 4

任何多少个命令库也与之类似。倘诺你的程序要求诸如Open,Save,Stop,Play等标准命令,那就从未须求本身申明了,直接拿命令库来用就好了。

1.5         命令参数

这段日子提到的命令Curry面有无数WPF预制命令,如New,Open,Copy,Cut,Paste等。那些命令都以ApplicationCommands类的静态属性,所以它们的实例永久只好有三个,那就引起了二个标题:假使界面上有四个按钮二个用来创立Student档案,一个用来成立Teacher档案。都使用New命令的话,程序应该怎么区分新建的是哪些档案呢?

答案是使用CommandParameter,命令源一定是落到实处了ICommandSource接口的目的,而ICommandSource有二个性能便是CommandParameter,假若把命令看作飞向指标的炮弹,那么CommandParameter就一定于装载在炮弹里面包车型地铁“新闻”。下边是程序的贯彻代码。

XAML代码如下:

[html] view plaincopyprint?

 

 

  1. <Window x:Class="WpfApplication1.Window29"  
  2.         xmlns=""  
  3.         xmlns:x=""  
  4.         Title="Window29" Height="278" Width="398">  
  5.     <Grid>  
  6.         <Grid.RowDefinitions>  
  7.             <RowDefinition Height="24" />  
  8.             <RowDefinition Height="4" />  
  9.             <RowDefinition Height="24" />  
  10.             <RowDefinition Height="4" />  
  11.             <RowDefinition Height="24" />  
  12.             <RowDefinition Height="4" />  
  13.             <RowDefinition Height="*" />  
  14.         </Grid.RowDefinitions>  
  15.         <!--命令和指令参数-->  
  16.         <TextBlock  HorizontalAlignment="Left" Name="textBlock1" Text="Name:" VerticalAlignment="Center" Grid.Row="0"/>  
  17.         <TextBox x:Name="txtName" Margin="60,0,0,0" Grid.Row="0"></TextBox>  
  18.         <Button Content="New Teacher" Grid.Row="2" Command="New" CommandParameter="Teacher"></Button>  
  19.         <Button Content="New Student" Grid.Row="4" Command="New" CommandParameter="Student"></Button>  
  20.         <ListBox Grid.Row="6" x:Name="lbInfos">  
  21.               
  22.         </ListBox>  
  23.     </Grid>  
  24.     <!--为窗体加多CommandBinding-->  
  25.     <Window.CommandBindings>  
  26.         <CommandBinding Command="New" CanExecute="CommandBinding_CanExecute" Executed="CommandBinding_Executed">  
  27.               
  28.         </CommandBinding>  
  29.     </Window.CommandBindings>  
  30. </Window>  

如上代码有七个地点须要注意:

五个按键都选用的是New命令,但各自选拔的是Student和Teacher做为的参数。

这一次是使用XAML代码为窗体增添CommandBinding,Commandbinding的CanExecute和Executed事件管理器写在后台C#代码里:

[csharp] view plaincopyprint?

 

 

  1. private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)  
  2. {  
  3.     if (string.IsNullOrEmpty(txtName.Text))  
  4.     {  
  5.         e.CanExecute = false;  
  6.     }  
  7.     else  
  8.     {  
  9.         e.CanExecute = true;  
  10.     }  
  11.     //路由停下,升高系统品质  
  12.     e.Handled = true;  
  13. }  
  14.   
  15. private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)  
  16. {  
  17.     if (e.Parameter.ToString() == "Student")  
  18.     {  
  19.         this.lbInfos.Items.Add(string.Format("New Student:{0} 好好学习,每一天向上。",txtName.Text));  
  20.     }  
  21.     else if(e.Parameter.ToString()=="Teacher")  
  22.     {  
  23.         this.lbInfos.Items.Add(string.Format("New Teacher:{0} 学而不厌,孜孜不倦。", txtName.Text));  
  24.     }  
  25.     //路由停下,提高系统性情  
  26.     e.Handled = true;  
  27. }  

运转程序,当Text博克斯中尚无内容的时候,七个开关都不可用;当输入文字后开关变为可用,单击按键,ListBox中会增添不一样的条文,效果如下图:

图片 5  图片 6

1.6         命令于Binding结合

初试命令,你也许会想到这么二个标题,控件那么多事件,可以让大家进行各个各样的不如操作,可控件独有二个Command属性、而下令库却有数10种命令,那样怎么恐怕行使那个独一的Command属性来调用那么多样下令呢?答案是行使BIndding。前边已经说过,Binding作为一种直接的、不稳固的赋值手腕,能够令你有机缘采纳在有些条件下为目的赋特定的值(有的时候候需求注重Converter)。

例如一个Button所涉及的下令有望依照一些条件而改造,大家得以把代码写成那样:

[html] view plaincopyprint?

 

 

  1. <Button x:Name="cmdBtn" Command="{Binding Path=ppp, Source=sss}" Content="Command"></Button>  

而是话又说回来了,因为好多指令开关都有相对应的图标来代表一定的意义,所以普通工作中三个控件的通令一经鲜明非常少更动。

 

2.0            近观命令

一般景观下,程序中选拔于逻辑非亲非故的RoutedCommand来跑跑龙套就够用了,但为了让程序的结构更为从简(举例去掉外围的CommandBinding和与之相关的事件管理器),大家常需求定义本身的命令。本节中大家走进WPF命令,先由RoutedCommand入手,再次创下设自身的通令。

2.1          ICommand接口与RoutedCommand

WPF中的命令是落到实处了ICommand接口的类。ICommand接口极其简单,只包蕴四个章程和叁个平地风波:

Execute方法:命令奉行,恐怕说命令试行于命令指标之上。要求注意的是,现实世界中的命令是不会融洽奉行的,而这里,试行成为了命令的格局,有一点点拟人化的含意。

CanExecute方法:在实行在此之前探知命令是还是不是足以实践。

CanExecuteChanged事件:当命令的可实市价况退换的时候,可激情那一件事件通报任何对象。

RoutedCommand便是一个达成了ICommand接口的类。RoutedCommand在贯彻ICommand接口时,并没有向Execute和CanExecute方法中加上其余逻辑,也正是说,它是通用的、与具象的事体逻辑非亲非故的。怎么通晓“与实际的政工逻辑无关那句话呢”?我们从外表和中间两有个别来精晓。

丛外界来看,大家回想一下ApplicationCommands命令Curry的下令们:

 

图片 7

虽说它们都有谈得来的名字,但它们都以平凡的RoutedUICommand实例。也正是说,当贰个下令达到命令目的之后,具体实行Copy或Cut即专门的学问逻辑不是由命令来支配的,而是由外面包车型客车CommandBinding捕获到命令目的受命令激发而发送的路由事件后在其Executed事件管理器中做到的。换句话说,固然你的CommandBInding在捕捉的Copy命令后试行的是破除操作,也与命令非亲非故。

从在这之中深入分析,大家将在看看RoutedCommand的源码了。RoutedCommand类与命令试行有关的代码简化如下:

图片 8

图片 9

开卷代码大家能够发掘,从ICommand接口承继来的Execute并不曾被公开(以致可以说抛弃不用了),仅仅是调用新证明的带多少个参数的Execute方法,新注脚的带五个参数的Execute方法是对伯公开的,能够选择第二个参数向命令传递一些数量,第二个参数是命令的指标,如果目的为null,Execute就能够把当下有所宗旨的控件当作自身的对象。新的Execute方法会调用命令实施逻辑的着力----ExecuteImpl方法(ExecuteImpl是Execute Implement的缩写),而以此法子内部并未有怎么秘密的地方,简要来讲正是“借用”命令指标的Raise伊芙nt把Routed伊夫nt发送出去。显著那么些事件会被外部的CommandBInding捕获然后实践程序猿预设的与作业逻辑相关的事物。

最后我们用ButtonBase为例来拜候UI成分是怎么发送命令的。ButtonBase是在Click发生的时候发送命令的,而Click事件的激情放在OnClick方法里面,ButtonBase的OnClick方法如下:

图片 10

Button调用了二个.netframeWorke里头的中间类(这几个类未有向程序员暴光)CommandHelpers的ExecuteCommandSource方法,并把ButtonBase对象本身看做参数字传送了进来。假如我们走进ExecuteCommandSource方法内部会意识那几个法子其实是吧传进来的参数当作命令源、调用命令源的ExecuteCore方法(本质上是调用了ExecuteImpl方法),获取命令源的CommandTarget属性值(命令指标)并义务令功用于命令目的之上。

图片 11

2.2      制定自定义Command

聊起自定义命令,我们得以分为四个档案的次序来驾驭。第八个档期的顺序相比较浅,指的是当WPF命令Curry面没有满含想要的授命时,大家就得表明自个儿定义的RoutedCommand实例。例如您想让命令目的在命令达到时发生笑声,WPF命令Curry面没有这些命令,那就能够和谐定五个Laugh的RoutedCommand实例。很难说那是一种真正含义上的自定义命令,那只是对RoutedCommand的行使。第二个档次是指从持续ICommand接口起头,第一谈得来的吩咐并把一些事情逻辑包括在指令里,那才称得上是确实含义上的自定义命令。但相比为难的是,在WPF系统中,命令源(ButtonBase,MenuItem,ListBoxItem,Hyperlink)、RoutedCommand和CommandBinding三者相互重视的一定严密。在源码等级上,不但未有将指令相关的主意申明为Virtual以供我们重写,何况还恐怕有繁多未向程序公开的逻辑(举例对ExecuteCore和CanExecuteCore那个方式的注明和调用)。换句话说,WPF中的命令源和CommandBinding就是特地为RoutedCommand编写的,借使我们想行使自身的ICommand派生类就必得连命令源一同落到实处(即落到实处IComamndSource接口)。因而为了便利的施用WPF那套成熟的类别,为了更高功能的“从0开首”塑造和煦的吩咐系统,要求大家依据项指标实际上意况开展度量。

既然本节名称为自定义命令,那么我们就从ICommand接口开头,营造一个纯手工业的自定义命令。

为了简化CommandBinding来管理程序业务逻辑的程序结构,大家兴许希望把事情逻辑移入命令的Execute方法内。比方大家能够自定义二个Save的下令,当命令达到命令指标的时候先通过命令目的的IsChanged属性决断命令目的的类容是不是早就改成,如若更改,命令能够实行,命令执行会间接调用命令目的的Save方法,驱动命令目的以投机的方式去保存数据。很显眼,那回是命令直接在命令指标上起效用了,而不像RoutedCommand那样今后目的上激起出路由事件等外围控件来捕获到路由事件过后“翻过头来”对命令目的加以管理。你大概会问,如若命令指标不含有IsChanged和Save方法如何是好?那就要靠接口来约束了,比方我们在程序中定义那样二个接口:

[csharp] view plaincopyprint?

 

 

  1. public interface IView  
  2. {  
  3.     //属性  
  4.     bool IsChanged { get; set; }  
  5.     //方法  
  6.     void SetBinding();  
  7.     void Refresh();  
  8.     void Clear();  
  9.     void Save();  
  10. }  

并且供给各种接收命令的组件必得贯彻那么些接口,这样能够确认保证命令能够对其实行操作。

接下去大家落到实处ICommand接口,成立一个特地职能于IView派生类的一声令下。

[csharp] view plaincopyprint?

 

 

  1. /// <summary>  
  2. ///自定义命令  
  3. /// </summary>  
  4. public class ClearCommand:ICommand  
  5. {  
  6.     //用来决断命令是还是不是足以推行  
  7.     public bool CanExecute(object parameter)  
  8.     {  
  9.         throw new NotImplementedException();  
  10.     }  
  11.     //当命令可实践景况发送改换时,应当被激发  
  12.     public event EventHandler CanExecuteChanged;  
  13.   
  14.     //命令施行时,带有与事务有关的Clear逻辑  
  15.     public void Execute(object parameter)  
  16.     {  
  17.         IView view = parameter as IView;  
  18.         if(view!=null)  
  19.         {  
  20.             view.Clear();  
  21.         }  
  22.     }  
  23. }  

指令完成了ICommand接口并三回九转了CanExecuteChanged事件、CanExecute方法、Execute方法。近日以此命令比较简单,只用到了Execute方法。在落到实处那些办法时,大家将以此点子独一的参数作为命令的对象,假设目的是IView接口的派生类则调用其Clear方法---分明大家曾经把程序的职业逻辑引进到了命令的Execute方法中。

有了自定义命令,大家利用什么命令源来“发射”它吗?前边说过,wpf中的命令源是专门为RoutedCommand计划的同不经常间无法重写,所以我们不得不通过落到实处ICommandSource接口来创设和睦的命令源,代码如下:

[csharp] view plaincopyprint?

 

 

  1. /// <summary>  
  2. /// MyCommandSource.xaml 的并行逻辑  
  3. /// </summary>  
  4. public partial class MyCommandSource : UserControl,ICommandSource  
  5. {  
  6.       
  7.     /// <summary>  
  8.     /// 继承自ICommand的3个属性  
  9.     /// </summary>  
  10.     public ICommand Command  
  11.     {  
  12.         get;  
  13.         set;  
  14.     }  
  15.   
  16.     public object CommandParameter  
  17.     {  
  18.         get;  
  19.         set;  
  20.     }  
  21.   
  22.     public IInputElement CommandTarget  
  23.     {  
  24.         get;  
  25.         set;  
  26.     }  
  27.     //在命令目的上实施命令,可能说让命令效用于命令目的  
  28.     protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)  
  29.     {  
  30.         base.OnMouseLeftButtonDown(e);  
  31.         if(this.CommandTarget!=null)  
  32.         {  
  33.             this.Command.Execute(CommandTarget);  
  34.         }  
  35.     }  
  36. }  

ICommand接口只蕴含Command,CommandParameter,CommandTarget  3个属性,至于那3个属性直接有何样的关系就看大家要怎么去达成了。在本例中CommandParameter完全未有被用到,而CommandTarget作为参数传递给了Command的Execute方法。命令不会融洽被产生,所以肯定要为命令的进行选择一个好的空子,本例中我们在控件左单击的时候实施命令。

现今下令和命令源都有了,还差二个下令目的。应该为我们的ClearCommand特意职能于IView派生类,所以合格的ClearCommand命令必需完毕IView接口。设计这种既有UI又必要实现接口的类能够先用XAML编辑器实习UI部分在转到后台用C#落到实处接口,原本很简短,WPF会自动为UI成分类增添partial关键字修饰,XAML代码会被翻译为类的一有个别,后台代码是类的一有个别,大家得以在后台代码部分自定基类也许完成接口,最后那几个代码会被编写翻译到手拉手。

其一组件的XAML部分如下:

[html] view plaincopyprint?

 

 

  1. <UserControl x:Class="WpfApplication1.MniView"  
  2.              xmlns=""  
  3.              xmlns:x=""  
  4.              xmlns:mc=""   
  5.              xmlns:d=""   
  6.              mc:Ignorable="d"   
  7.              d:DesignHeight="300" d:DesignWidth="300">  
  8.     <Border CornerRadius="5" BorderBrush="GreenYellow" BorderThickness="2">  
  9.         <StackPanel>  
  10.             <TextBox Margin="5" x:Name="txt1"></TextBox>  
  11.             <TextBox Margin="5" x:Name="txt2"></TextBox>  
  12.             <TextBox Margin="5" x:Name="txt3"></TextBox>  
  13.             <TextBox Margin="5" x:Name="txt4"></TextBox>  
  14.         </StackPanel>  
  15.     </Border>  
  16. </UserControl>  

它的后台代码部分如下:

[csharp] view plaincopyprint?

 

 

  1.  /// <summary>  
  2. /// MniView.xaml 的相互逻辑  
  3. /// </summary>  
  4. public partial class MniView : UserControl,IView  
  5. {  
  6.     //构造器  
  7.     public MniView()  
  8.     {  
  9.         InitializeComponent();  
  10.     }  
  11.     //承继自IView的成员们  
  12.     public bool IsChanged  
  13.     {  
  14.         get  
  15.         {  
  16.             throw new NotImplementedException();  
  17.         }  
  18.         set  
  19.         {  
  20.             throw new NotImplementedException();  
  21.         }  
  22.     }  
  23.   
  24.     public void SetBinding()  
  25.     {  
  26.         throw new NotImplementedException();  
  27.     }  
  28.   
  29.     public void Refresh()  
  30.     {  
  31.         throw new NotImplementedException();  
  32.     }  
  33.     /// <summary>  
  34.     /// 用于破除内容的事体逻辑  
  35.     /// </summary>  
  36.     public void Clear()  
  37.     {  
  38.         this.txt1.Clear();  
  39.         this.txt2.Clear();  
  40.         this.txt3.Clear();  
  41.         this.txt4.Clear();  
  42.     }  
  43.   
  44.     public void Save()  
  45.     {  
  46.         throw new NotImplementedException();  
  47.     }  
  48. }  

因为大家只演示Clear方法被调用,所以任何多少个艺术未有切实可行贯彻。当Clear方法被调用的时候,它的多少个TextBox会被清空。

末段把自定义命令,命令源,命令目的集成起来,窗体的XAML代码如下:

[html] view plaincopyprint?

 

 

  1. <Window x:Class="WpfApplication1.Window30"  
  2.         xmlns=""  
  3.         xmlns:x=""  
  4.         Title="Window30" Height="300" Width="300" xmlns:my="clr-namespace:WpfApplication1">  
  5.     <StackPanel>  
  6.         <my:MyCommandSource x:Name="myCommandSource1">  
  7.             <TextBlock Text="清除" Width="80" FontSize="16" TextAlignment="Center" Background="LightGreen"></TextBlock>  
  8.         </my:MyCommandSource>  
  9.         <my:MniView x:Name="mniView1" />  
  10.     </StackPanel>  
  11. </Window>  

本例中利用轻便的文本作为命令源的来得内容,实际专门的学业中得以采取Logo,开关或许更复杂的原委来填充它,但要适当更换激发命令的方式。不然你计划在里头放置二个按键,那么就无须用OnMouseLeftButtonDown的法子来试行命令了,而应该捕获button的Click事件并在事件管理器中实践措施(Mouse事件会被Button吃掉)。

后台C#代码:

[csharp] view plaincopyprint?

 

 

  1. /// <summary>  
  2. /// Window30.xaml 的相互逻辑  
  3. /// </summary>  
  4. public partial class Window30 : Window  
  5. {  
  6.     public Window30()  
  7.     {  
  8.         InitializeComponent();  
  9.         ClearCommand clearCommand = new ClearCommand();  
  10.         this.myCommandSource1.Command = clearCommand;  
  11.         this.myCommandSource1.CommandTarget = mniView1;  
  12.     }  
  13. }  

我们率先创设了二个ClearCommand实例并把它赋值给自定义命令源的Command属性,自定义命令源的CommandTarget属性目标是MiniView的实例。提示一句:为了讲解清晰才把命令放在此处,正规的主意应该是把命令申明为静态全局的地点供全数指标调用。运营程序,在TextBox里输入然后再单击清除控件,效果如下图:

图片 12图片 13

时至前几天,叁个简易的自定义命令就到位了,若想经过Command的CanExecute方法来影响命令源的状态,还亟需选择到ICommand和ICommandSource接口的积极分子结合更复杂的逻辑。

2018/1/10 19:06:35

指令能够约束代码,还足以约束步骤逻辑。(事件的法力是发布和扩散一些音信,对怎么响应事件不做规定,每一种接收者可以使用本人的行事来响应事件。也正是说事件不具备约束力)

命令系统的基本因素

·命令(Command):实际上正是兑现了ICommand接口的类,平日利用最多的是RoutedCommand类
·命令源(Command Source):实现了ICommandResource接口的类(Button)
·命令指标(Command Target):必须是落到实处了IInputCommand接口的类
·命令关联(Command Binding):负担把外围逻辑与命令关联起来,举个例子施行从前对命令是或不是足以实践实行判别、命令施行后还应该有怎么着后续工作等

指令的采纳

1.开立命令类

即取得三个实现ICommand接口的类,倘若命令与现实事务逻辑非亲非故,则运用WPF类库中的RoutedCommand就能够。假使想获取与事务逻辑相关的专有命令,则需求创立RoutedCommand(或然ICommand)的派生类。

2.注解命令实例

技艺:一般情形下,只须要操作多少个发令实例与之对应就可以。由从前后相继中的命令多选拔单件格局(Singletone Pattern)以收缩代码复杂度。

3.内定命令源

命令源具有命令和命令源七个属性。
同一个命令能够有两个源。
假若把命令指派给命令源,命令源就能够受命令影响,命令不能够举行的时候作为命令源的控件不可用。革命临官发送命令的格局不尽一样,比方单机双击。

4.点名命令目的

指令目的不是命令的质量而是命令源的品质。无论那几个命令源是或不是具备大旨都会收到这么些命令。若无一些名命令指标,默以为当前主题对象就是命令目的。

5.设置命令关联(命令绑定)

WPf供给CommandBinding在进行前协助判断是还是不是足以施行,在推行后做一些事件来“打扫战地”。命令目的向命令关联发送路由事件,命令关联捕捉并拍卖路由事件,向命令反馈消息。

本文由bg游戏资讯发布于单机闯关小游戏,转载请注明出处:简单理解,深入浅出话命令

关键词: .NET技术 WPF