无废话WPF系列14:命令

简介:

一、WPF为何需要命令

我们已经知道WPF里已经有了路由事件,可以发布及传播一些消息,那为什么还需要命令呢?这是因为事件指负责发送消息,对消息如何处理则不管,而命令是有约束力,每个接收者对命令执行统一的行为,比如菜单上的保存,工具栏上的保存都必须是执行同样的保存。

二、命令系统的基本元素

命令(Command):实现了ICommand接口的类,经常使用的有RoutedCommand类

命令源: 是命令的发送者,是实现了ICommandSource接口的类,大部分界面的控件都实现了这个接口,Button, MenuItem 等等。

命令目标:命令的接收者,命令目标是视线了IInputElement接口的类。

命令关联:负责一些逻辑与命令关联起来,比如判断命令是否可以执行,以及执行完毕后做一些处理。

三、四个命令元素之间的关系

image

四、命令示例

我们让一个按钮发送Hello命令给文本框,文本框接收这个命令后显示“Nice to meet you”.

1
2
3
4
5
6
7
8
9
10
11
12
13
< Window  x:Class="DeepXAML.MainWindow"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:local="clr-namespace:DeepXAML"      
         xmlns:sys="clr-namespace:System;assembly=mscorlib"
         Title="MainWindow" Height="250" Width="450">
    
     < StackPanel  x:Name="stackPanel">
         < TextBox  x:Name="textBox1" Margin="10"></ TextBox >
         < TextBox  x:Name="textBox2" Margin="10"></ TextBox >
         < Button  x:Name="btnHello" Margin="10">Hello</ Button >
     </ StackPanel >
</ Window >

 

后台代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
using  System;
using  System.Collections.Generic;
using  System.Windows;
using  System.Windows.Data;
using  System.Windows.Documents;
using  System.Windows.Controls;
using  System.Windows.Input;
 
namespace  DeepXAML
{
     public  partial  class  MainWindow : Window
     {
         private  RoutedCommand helloCmd = new  RoutedCommand( "Hello" , typeof (MainWindow));
 
         public  MainWindow()
         {
             InitializeComponent();
 
             this .btnHello.Command = this .helloCmd;
             this .helloCmd.InputGestures.Add( new  KeyGesture(Key.H, ModifierKeys.Alt));
             this .btnHello.CommandTarget = this .textBox1;
             this .btnHello.CommandTarget = this .textBox2;
 
             CommandBinding cb = new  CommandBinding();
             cb.Command = this .helloCmd;
             cb.CanExecute += new  CanExecuteRoutedEventHandler(cb_CanExecute);
             cb.Executed += new  ExecutedRoutedEventHandler(cb_Executed);
 
             this .stackPanel.CommandBindings.Add(cb);
         }
 
         void  cb_Executed( object  sender, ExecutedRoutedEventArgs e)
         {           
             this .textBox1.Text = "Nice to meet you" ;
             this .textBox2.Text = "Nice to meet you" ;
             e.Handled = true ;
            
         }
 
         void  cb_CanExecute( object  sender, CanExecuteRoutedEventArgs e)
         {
             if  (! string .IsNullOrEmpty(textBox1.Text) || ! string .IsNullOrEmpty(textBox2.Text))
             {
               e.CanExecute= false ;
             }
             else
             {
                 e.CanExecute = true ;
             }
 
             // 避免继续传递
             e.Handled = true ;           
         }
     }
}

 

执行时

一开始按钮状态可用,也就是命令可执行

image

点击按钮后:

image

清空一个TextBox,按钮仍然不可执行,因为没达到可执行的条件,两个都清空时,按钮重回可执行状态

 

 

五、WPF的命令库

WPF提供常用应用程序所用的命令集,常用的命令集包括:ApplicationCommands, ComponentCommands, NavigationCommands, MediaCommands和EditingCommands。 
ApplicationCommands(应用程序命令): 
CancelPrint:取消打印 
Close:关闭 
ContextMenu:上下文菜单 
Copy:复制 
CorrectionList: Gets the value that represents the Correction List command. 
Cut:剪切 
Delete:删除 
Find:查找 
Help:帮助 
New:新建 
NotACommand:不是命令,被忽略 
Open:打开 
Paste:粘贴 
Print:打印 
PrintPreview:打印预览 
Properties:属性 
Redo:重做 
Replace:取代 
Save:保存 
SaveAs:另存为 
SelectAll:选择所有的 
Stop:停止 
Undo:撤消 
ComponentCommands(组件命令): 
ExtendSelection:后接Down/Left/Right/Up, 比如:ExtendSelectionDown(Shift+Down,Extend Selection Down),ExtendSelectionLeft等 
Move:后接Down/Left/Right/Up, 如:MoveDown 
MoveFocus:后接Down/Forward/Back/Up, 如:MoveFocusDown 
MoveFocusPage:后接Down/Up,如:MoveFocusPageUp 
MoveTo:后接End/Home/PageDown/PageUp,比如:MoveToPageDown 
ScrollByLine 
ScrollPage:后接Down/Left/Right/Up,比如:ScrollPageLeft 
SelectTo:End/Home/PageDown/PageUp,比如:SelectToEnd 
NavigationCommands(导航命令): 
Browse浏览: 后接Back/Forward/Home/Stop, 比如:BrowseBack 
缩放显示:DecreaseZoom, IncreaseZoom, Zoom 
Favorites(收藏) 
页面:FirstPage, LastPage, PreviousPage, NextPage,GoToPage 
NavigateJournal 
Refresh(刷新) 
Search(搜索) 
MediaCommands(多媒体控制命令): 
Treble高音:DecreaseTreble,IncreaseTreble 
Bass低音:BoostBass,DecreaseBass,IncreaseBass 
Channel频道:ChannelDown,ChannelUp 
MicrophoneVolume麦克风音量调节:DecreaseMicrophoneVolume,IncreaseMicrophoneVolume,MuteMicrophoneVolume 
ToggleMicrophoneOnOff:麦克风开关 
Volume音量: DecreaseVolume,IncreaseVolume,MuteVolume 
Rewind, FastForward(回放,快进) 
Track轨道:PreviousTrack,NextTrack [上一段(节)] 
Play,Pause,Stop,Record(播放,暂停,停止,录制) 
TogglePlayPause 
Select选择 
EditingCommands(编辑/排版类命令): 
Align对齐:AlignCenter,AlignJustify,AlignLeft,AlignRight(居中,撑满,左对齐,右对齐) 
Backspace退格 
TabForward,TabBackward(Tab前缩,Tab向后) 
FontSize字体大小:DecreaseFontSize,IncreaseFontSize 
Indentation缩排:DecreaseIndentation, IncreaseIndentation 
Delete删除: Delete选中部分,DeleteNextWord:删除后一字,DeletePreviousWord:删除前一字 
EnterLineBreak:换行 
EnterParagraphBreak:换段 
CorrectSpellingError/IgnoreSpellingError:纠正/忽略拼写错误 
MoveUpByLine,MoveDownByLine: 上/下移一行, 
MoveUpByPage,MoveDownByPage: 上/下移一页 
MoveUpByParagraph,MoveDownByParagraph: 上/下移一段 
MoveLeftByCharacter/MoveRightByCharacter:左/右移一字符 
MoveLeftByWord/MoveRightByWord 左/右移一词 
MoveToDocumentStart/MoveToDocumentEnd:到文章开头/结尾 
MoveToLineStart/MoveToLineEnd:到一行的开头/结尾 
SelectUpByLine,SelectDownByLine:向上/下选一行 
SelectUpByPage,SelectDownByPage:向上/下选一页 
SelectUpByParagraph,SelectDownByParagraph:向上/下选一段 
SelectLeftByCharacter,SelectRightByCharacter:向左/右选中一字 
SelectLeftByWord,SelectRightByWord:向左/右选中一词 
SelectToDocumentStart,SelectToDocumentEnd: 选中到篇头/篇尾 
SelectToLineStart/SelectToLineEnd:选中到行首/行尾 
ToggleBold, ToggleItalic, ToggleUnderline(加粗,斜体,下划线) 
ToggleBullets, ToggleNumbering(列表:加点,加数字) 
ToggleInsert:插入 
ToggleSuperscript,ToggleSubscript(上标字,下标字)

 

六、命令参数

命令大部分都是类的静态属性,也就是示例只有一个,那么如果两个按钮使用同一个命令如何区分呢?比如新建一个Project,如何区分新建的是Library还是WPF呢?我们可以使用CommandParameter

XAML:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
< Window  x:Class="DeepXAML.MainWindow"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:local="clr-namespace:DeepXAML"      
         xmlns:sys="clr-namespace:System;assembly=mscorlib"
         Title="MainWindow" Height="250" Width="450">
     < Window.CommandBindings >
         < CommandBinding  Command="New" CanExecute="New_CanExecute" Executed="New_Executed"></ CommandBinding >
     </ Window.CommandBindings >
         < StackPanel  x:Name="stackPanel">       
         < TextBox  x:Name="textBox" Margin="10"></ TextBox >
         < Button  x:Name="btnWPF" Margin="10" Command="New" CommandParameter="WPF">新建WPF</ Button >
         < Button  x:Name="btnLibrary" Margin="10" Command="New" CommandParameter="Library">新建Library</ Button >
     </ StackPanel >
</ Window >

后台代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
using  System;
using  System.Collections.Generic;
using  System.Windows;
using  System.Windows.Data;
using  System.Windows.Documents;
using  System.Windows.Controls;
using  System.Windows.Input;
 
namespace  DeepXAML
{
     public  partial  class  MainWindow : Window
     {
 
         public  MainWindow()
         {
             InitializeComponent();
         }
 
         private  void  New_CanExecute( object  sender, CanExecuteRoutedEventArgs e)
         {
             e.CanExecute = string .IsNullOrEmpty(textBox.Text);
         }
 
         private  void  New_Executed( object  sender, ExecutedRoutedEventArgs e)
         {
             if  (e.Parameter.ToString() == "Library" )
             {
                 this .textBox.Text+= "建一个Library" ;
             }
             if  (e.Parameter.ToString() == "WPF" )
             {
                 this .textBox.Text += "建一个WPF" ;
             }           
         }
     }          
}

 

运行:

image

点击第一个按钮

image

清空文本框再点击第二个按钮

image

本文转自敏捷的水博客园博客,原文链接http://www.cnblogs.com/cnblogsfans/archive/2011/02/27/1966167.html如需转载请自行联系原作者


王德水

相关文章
|
前端开发 C#
WPF 之 数据与命令绑定 (MVVM方式)
WPF 之 数据与命令绑定 (MVVM方式)
160 0
WPF 之 数据与命令绑定 (MVVM方式)
|
前端开发 C# 数据格式
WPF MVVM模式中,通过命令实现窗体拖动、跳转以及显隐控制
原文:WPF MVVM模式中,通过命令实现窗体拖动、跳转以及显隐控制 在WPF中使用MVVM模式,可以让我们的程序实现界面与功能的分离,方便开发,易于维护。但是,很多初学者会在使用MVVM的过程中遇到一个显而易见且无法回避的问题,那就是不同的窗体之间如何跳转?很多人在介绍MVVM的使用时,都没有明显提到该如何解决这一问题,不知是因为觉得太简单了还是其他原因。
2505 0
|
C# 容器
WPF命令
原文:WPF命令 “有了路由事件为什么还需要命令系统呢?”。事件的作用是发布、传播一些消息,消息传达到了接收者,事件的指令也就算完成了,至于如何响应事件送来的消息事件并不做任何限制,每个接收者可已用自己的行为来响应事件。
805 0
|
C#
【C#/WPF】图像变换的Undo撤销——用Stack命令栈
原文:【C#/WPF】图像变换的Undo撤销——用Stack命令栈 需求: 图层中有一张图片,可以对该图层进行平移、缩放、旋转操作,现在要求做Undo撤销功能,使得图层回复上一步操作时的状态。
842 0
|
C#
WPF 事件触发命令
原文:WPF 事件触发命令 方法一使用mvvmlight: xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.
1540 0