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

作者: 单机游戏资讯  发布:2019-05-20

命令(Command)

转自:

WPF为我们盘算了一应俱全的下令系统,你可能会问:“有了路由事件为何还索要命令系统吧?”。事件的功能是公布、传播一些音讯,新闻传到达了收信人,事件的授命也即使完成了,至于如何响应事件送来的音信事件并不做任何限制,各样接收者可已用自个儿的行为来响应事件。也正是说,事件不持有约束力。命令和事件的分别就在于命令具有约束力。

实在,在实质上编制程序专业中,即使只用事件并非命令程序的逻辑同样被驱动的很好,但我们不能拦截技士根据本人的习贯去编写代码。举个例子保留事件的微管理器,技士能够写Save()、SaveHandle()、SaveDocument()... 这么些都严丝合缝代码标准。但迟早有一天整个项目会变的令人不能读懂,新来的程序猿或修改bug的程序猿会很抓狂。假如选取命令,景况就能够好广大----当Save命令达到有个别组件的时候,命令会活动去调用组件的Save方法。而以此措施大概定义在基类或许接口里(即确认保证了那么些方式是肯定期存款在的),那就在代码结交涉命名上做了约束。不但如此,命令还可调整接收者“先做校验,再保存,最后退出”,也便是说命令除了能够约束代码,还足以约束步骤逻辑,让新来的工程师想犯错都难,也让老大修改Bug的程序员轻松找到规律,轻巧上手。

一.一      命令系统的着力要素和涉及

 

  • WPF的下令系统由多少个基本要素构成,它们是:
  • 简单理解,深入浅出话命令。一声令下(Command):WPF的吩咐实际上便是贯彻了ICommand接口的类,平时采纳最多的就是RoutedCommand类。我们还会学习运用自定义命令。
  • 命令源(Command Source):即命令的发送者,是落到实处了ICommandSource接口的类。多数分界面元素都落到实处了那么些接口,个中包罗Button,ListBoxItem,MenuItem等。
  • 命令指标(Command Target):即命令发送给哪个人,也许说命令成效在何人的身上。命令目的必须是兑现了IInputElement接口的类。
  • 命令关联(Command Binding):担负把1部12分场逻辑和指令关联起来,比方执行在此之前对命令是不是能够进行进行决断、命令施行之后还有怎么着后续工作等。

1.贰      基本要素之间的关联

那几个骨干要素的涉及映以后使用命令的进度中。命令的应用大约分为以下几步:

(壹)创制命令类:即得到2个落实ICommand接口的类,若是命令与具象的政工逻辑无关则使用WPF类库中的(RoutedCommand)类就可以。要是想获取与作业逻辑相关的专有命令,则需求创制RoutedCommand(大概ICommand接口)的派生类。

(二)注解命名实例:使用命令时索要创立命令类的实例。这里有多少个技巧,一般情形下程序中某种操作只必要二个限令实例与之对应就能够。比方对应“保存”那几个命令操作。因而先后中的命令多应用单件情势以缩减代码的复杂度。

(三)内定命令的源:即钦点由什么人来发送命令。借使把命令看作炮弹,那么命令源就一定于火炮。同1个发令能够有几个源。比方保留命令,即能够由菜单中的保存项来发送,也能够由保存工具栏中的图标进行发送。需求注意的是,壹旦把命令指派给了命令源,那么命令源就能受命令的影响,当命令无法被实施的时候命令源的控件处于不可用状态。看来命令这种炮弹还很智能,当不满意发送条件的时候还会给用来发出它的大炮上壹道保证、幸免走火。还索要小心,各样控件发送命令的方法不经同样,比方Button和MenuButton在单击时发送命令,而ListBoxItem单击时表示被入选,双击的时候才发送命令。

(4)指令命令目的:命令指标并不是命令的质量,而是命令源的品质。钦命命令目的是报告命令源向哪些组件发送命令。无论这一个组件是不是持有主题他都会抽取这几个命令。借使未有为源内定命令指标,则WPF系统以为当前持有宗旨的对象正是命令目的。这一个手续有点像为火炮钦命目的。

简单理解,深入浅出话命令。(五)设置命令关联:炮兵是不能够独立大战的,就像炮兵在规划前边需求特种兵阅览敌情、推断发射时机,在射击后观望射击效果,帮衬校订相同。WPF命令要求CommandBinding在实施在此以前来赞助推断是还是不是足以实施、在实施后做一些事来“打扫沙场”。

简单理解,深入浅出话命令。在命令目的和下令关联之间还有局地微妙的关联。无论命令指标是由程序员钦命依旧由WPF系统依照难点所在地推断出来的,1旦有个别UI组件被下令源瞄上,命令源就能够持续的向命令指标投砾引珠,命令指标就能够不停的发送可路由的PreviewCanExecute和CanExecute附加事件。事件会沿UI成分树向上传递并被下令关联所擒获,命令关联会成功部分继续职务。别小看“后续职分”,对于这几个事情逻辑无关的通用命令,这个后续职分才是最要害的。

您或然会问:“命令指标怎么会发生PreviewCanExecute、CanExecute、PreviewExecute和Executed事件吧?”其实那多个事件都是增大事件,是被CommandManager类“附加”给命令指标的。我们能够翻过头来再理解一下增大事件。其余,PreviewCanExecute和CanExecute的实施时机不由程序猿调控,而且实行功能相比高,那不仅给系统性格带来了些降低,临时还会引进多少个意料之外的BUG并且相比难调节和测试,请大家必须多加小心。

下图所示是WPF命令系统主旨要素的关系图:

图片 1

1.叁         小试命令

提起来很繁华,未来让大家起始施行一下。完成如此三个供给:定义二个指令,使用Button来发送这些命令,当命令抵达TextBox的时候,TextBox会被清空(借使TextBox没有文字,命令不可用。)。

程序XAML代码如下:

[html] view plaincopyprint?

 

 

  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.     /// Window2八.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是1个与事务逻辑非亲非故的类,只肩负在程序中跑腿而并不对命令目的展开操作,TextBox并不是由它清空的。那么TextBox的情形操作是何人吧?答案是CommandBinding。因为无论是探测命令是不是足以施行或然命令送达目的,都会激发命令目的发送路由事件,那个事件会沿着UI成分树向上传递,最后被CommandBinding所捕捉。本例中CommandBinding被安装在外面包车型大巴StackPanel上,Commandbinding站在高处起二个侦听器的成效,而且极度针对rouutedCommand命令捕捉与其有关的轩然大波。本例中,当CommandBinding捕捉到CanExecute就能够调用cb_CanExecute方法。当捕捉到是Executed的时候,就调用cb_Execute事件。

其三,因为CanExecute事件的振作频率比较高,为了防止降低品质,在管理完结之后提议将e.Handle设置为true。

第5,CommandBinding一定要设置在指令指标的外场控件上,否则不大概捕捉CanExecute和Executed等路由事件。

一.四         WPF中的命令库

地点那一个例子中,我们团结证明定义了七个命令:

[csharp] view plaincopyprint?

 

 

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

一声令下具有一处证明,四处使用的本性,比方Save命令,在先后的别样地方它都代表供给命令目的保存数据。由此,微软在WPF类Curry面希图了1部分简便的命令库,那些命令库包罗:

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等规范命令,那就平昔不须求本人表明了,直接拿命令库来用就好了。

一.伍         命令参数

眼下提到的命令Curry面有那些WPF预制命令,如New,Open,Copy,Cut,Paste等。那么些命令都是ApplicationCommands类的静态属性,所以它们的实例长久只好有二个,那就引起了多少个主题素材:假使分界面上有八个按键1个用来制造Student档案,3个用来创制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. }  

运维程序,当TextBox中绝非内容的时候,三个开关都不可用;当输入文字后开关变为可用,单击按键,ListBox中会增添区别的条条框框,效果如下图:

图片 5  图片 6

1.6         命令于Binding结合

初试命令,你或然会想到那样1个题目,控件那么多事件,能够让大家开始展览有滋有味的例外操作,可控件唯有3个Command属性、而下令库却有数10种命令,那样怎么大概应用这一个唯一的Command属性来调用那么二种命令呢?答案是使用BIndding。前边早已说过,Binding作为壹种直接的、不牢固的赋值花招,能够让您有空子选拔在有些条件下为目的赋特定的值(有的时候候须要注重Converter)。

比如说1个Button所关联的指令有相当的大希望依照一些条件而更改,我们得以把代码写成这么:

[html] view plaincopyprint?

 

 

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

但是话又说回去了,因为诸多指令开关都有相对应的Logo来代表一定的意思,所以一般职业中3个控件的通令1经分明很少改变。

 

二.0            近观命令

诚如景色下,程序中采用于逻辑无关的RoutedCommand来跑跑龙套就丰盛了,但为了让程序的构造进一步简明(比如去掉外围的CommandBinding和与之互为表里的轩然大波处理器),大家常供给定义本身的指令。本节中大家走进WPF命令,先由RoutedCommand动手,再成立本身的授命。

2.1          ICommand接口与RoutedCommand

WPF中的命令是落到实处了ICommand接口的类。ICommand接口特别轻巧,只包括三个办法和1个轩然大波:

Execute方法:命令试行,或许说命令实行于命令指标之上。供给留意的是,现实世界中的命令是不会友善施行的,而那边,试行成为了指令的办法,有一些拟人化的意味。

CanExecute方法:在实行从前探知命令是还是不是足以进行。

CanExecuteChanged事件:当命令的可施行情状退换的时候,可激情此事件通报别的对象。

RoutedCommand正是2个兑现了ICommand接口的类。RoutedCommand在落到实处ICommand接口时,并未有向Execute和CanExecute方法中增添任何逻辑,约等于说,它是通用的、与实际的工作逻辑非亲非故的。怎么驾驭“与现实的作业逻辑毫无干系那句话呢”?大家从表面和里面两有的来领会。

丛外部来看,我们回顾一下ApplicationCommands命令Curry的下令们:

 

图片 7

虽说它们都有谈得来的名字,但它们都以平时的RoutedUICommand实例。也正是说,当一个下令达到命令指标之后,具体进行Copy或Cut即职业逻辑不是由命令来调节的,而是由外界的CommandBinding捕获到命令目的受命令激发而发送的路由事件后在其Executed事件管理器中完毕的。换句话说,纵然你的CommandBInding在捕捉的Copy命令后施行的是革除操作,也与命令非亲非故。

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

图片 8

图片 9

阅读代码我们得以窥见,从ICommand接口承接来的Execute并从未被公开(以至可以说扬弃不用了),仅仅是调用新注解的带多个参数的Execute方法,新表明的带七个参数的Execute方法是对曾祖父开的,能够行使第三个参数向命令传递一些数量,第2个参数是命令的目的,如果目的为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

二.二      制定自定义Command

提及自定义命令,我们能够分成多个等级次序来精晓。第贰个档案的次序相比较浅,指的是当WPF命令Curry面未有包罗想要的一声令下时,我们就得评释自身定义的RoutedCommand实例。比方你想让命令目标在指令到达时产生笑声,WPF命令Curry面未有这些命令,那就能够和睦定3个Laugh的RoutedCommand实例。很难说这是1种真正含义上的自定义命令,那只是对RoutedCommand的利用。第一个等级次序是指从一连ICommand接口开端,第一本身的一声令下并把一些事情逻辑包涵在指令里,那才称得上是当真含义上的自定义命令。但比较吃力的是,在WPF系统中,命令源(ButtonBase,MenuItem,List博克斯Item,Hyperlink)、RoutedCommand和CommandBinding三者互相依赖的格外严密。在源码等第上,不但未有将指令相关的措施评释为Virtual以供大家重写,而且还有众多未向程序公开的逻辑(例如对ExecuteCore和CanExecuteCore这么些方法的扬言和调用)。换句话说,WPF中的命令源和CommandBinding就是特地为RoutedCommand编写的,假使大家想行使本人的ICommand派生类就必须连命令源一同落到实处(即实现IComamndSource接口)。由此为了省事的使用WPF那套成熟的体系,为了更加高成效的“从0伊始”营造谐和的一声令下系统,要求大家依据项目标莫过于意况举行度量。

既然本节名称为自定义命令,那么大家就从ICommand接口起先,塑造2个纯手工业的自定义命令。

为了简化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接口,创立3个专程职能于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  二个属性,至于那三个属性直接有怎样的涉及就看大家要怎么去贯彻了。在本例中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的实例。提示一句:为了讲授清晰才把命令放在此处,正规的不二等秘书诀应该是把命令表明为静态全局的地点供全体目的调用。运转程序,在Text博克斯里输入然后再单击清除控件,效果如下图:

图片 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)的派生类。

二.宣称命令实例

才具:一般景象下,只供给操作三个下令实例与之对应就能够。由此先后中的命令多应用单件情势(Singletone Pattern)以调整和裁减代码复杂度。

三.钦定命令源

命令源具备命令和命令源多少个属性。
同一个发令能够有八个源。
假诺把命令指派给命令源,命令源就能够受命令影响,命令无法实践的时候作为命令源的控件不可用。革命临官发送命令的主意不尽同样,比如单机双击。

四.点名命令指标

一声令下目的不是命令的习性而是命令源的习性。无论那几个命令源是不是富有主题都会吸收接纳那么些命令。如若未有一点名命令目的,默以为当前火热对象便是命令指标。

五.安装命令关联(命令绑定)

WPf要求CommandBinding在实行前扶掖决断是或不是足以试行,在进行后做一些风云来“打扫战地”。命令目的向命令关联发送路由事件,命令关联捕捉并拍卖路由事件,向命令反馈新闻。

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

关键词: 单机 WPF .NET技术

上一篇:没有了
下一篇:没有了