WPF 命令绑定简单应用

UI交互时,很多功能都是有不同的入口来实现,例如:复制、粘贴等。早期winform编程的时候一般都是通过抽取方法,然后事件调用方法来实现代码复用。WPF提供了命令这一模式来实现这一应用 - 一功能、多入口。

WPF的一个命令系统是被分为四个部分:

1. Command(命令):一个语义级别的输入,比如“复制”等;

2. CommandSource(命令源):引发某命令的元素,比如按钮,菜单项,键盘(Ctrl-C,F1等),鼠标等;

3. CommandTarget(命令目标):命令被作用的目标,比如文本框,播放器等;

4. CommandBinding(命令绑定):用于将命令和命令的处理逻辑链接起来,比如同样的"粘贴",但粘贴文本和粘贴图片的处理逻辑是不一样的,命令绑定负责将“粘贴”命令与合理的处理逻辑连接起来。

 

其中,命令源是由引发命令的元素实现的,在WPF现有的控件中,如:MenuItem、ButtonBase等。而命令目标是由接收命令的元素实现,使用时属于非必须项。

 

下面是个简单的例子:

1. 界面定义和绑定命令:

 

 

[c-sharp] view plain copy
 
  1. <!--窗口命令绑定定义-->  
  2. <Window.CommandBindings>  
  3.     <CommandBinding Command="Undo"   
  4.                     CanExecute="CommandBinding_Undo_CanExecute"  
  5.                     Executed="CommandBinding_Undo_Execute"/>  
  6.     <CommandBinding Command="Redo"   
  7.                     CanExecute="CommandBinding_Redo_CanExecute"  
  8.                     Executed="CommandBinding_Redo_Execute"/>  
  9.     <CommandBinding Command="Zoom"   
  10.                     Executed="CommandBinding_Zoom_Execute"/>  
  11. </Window.CommandBindings>  
  12.   
  13. <!--窗口输入命令绑定定义-->  
  14. <Window.InputBindings>  
  15.     <KeyBinding Command="Undo" Key="Z" Modifiers="Control" />  
  16.     <KeyBinding Command="Redo" Key="Y" Modifiers="Control" />  
  17. </Window.InputBindings>  

  

 

 

[c-sharp] view plain copy
 
  1. <Menu x:Name="TopMenu"  DockPanel.Dock="Top" >  
  2. <MenuItem x:Name="MenuEditItem" Header="编 辑">  
  3.                 <MenuItem x:Name="MenuUndoItem" Header="撤 销" Command="Undo" />  
  4.                 <MenuItem x:Name="MenuRedoItem" Header="重 做" Command="Redo" />  
  5.             </MenuItem>  
  6.         </Menu>  
  7.  <!--窗口底部菜单-->  
  8.         <Menu x:Name="BottomMenu" DockPanel.Dock="Bottom">  
  9.             <!--画板缩放菜单-->  
  10.             <MenuItem x:Name="MenuZoomItem" Header="缩放比例:100%">  
  11.                 <MenuItem Header="50%" Command="Zoom" CommandParameter="50" />  
  12.                 <MenuItem Header="75%" Command="Zoom" CommandParameter="75" />  
  13.                 <MenuItem Header="100%" Command="Zoom" CommandParameter="100" />  
  14.                 <MenuItem Header="120%" Command="Zoom" CommandParameter="120" />  
  15.                 <MenuItem Header="150%" Command="Zoom" CommandParameter="150" />  
  16.                 <MenuItem Header="200%" Command="Zoom" CommandParameter="200" />  
  17.                 <MenuItem Header="300%" Command="Zoom" CommandParameter="300" />  
  18.                 <MenuItem Header="400%" Command="Zoom" CommandParameter="400" />  
  19.                 <MenuItem Header="500%" Command="Zoom" CommandParameter="500" />  
  20.             </MenuItem>  
  21.         </Menu>  

 

 

2. 后台代码实现: 

 

[c-sharp] view plain copy
 
  1. #region Window Command          
  2.         /// <summary>  
  3.         /// 可否执行撤销命令判断  
  4.         /// </summary>  
  5.         /// <param name="sender">Command</param>  
  6.         /// <param name="e">event arg</param>  
  7.         private void CommandBinding_Undo_CanExecute(object sender, CanExecuteRoutedEventArgs e)  
  8.         {  
  9.             if (null == this.diagram.UndoManager.History.NextUndo)  
  10.             {  
  11.                 e.CanExecute = false;  
  12.             }  
  13.             else  
  14.             {  
  15.                 e.CanExecute = true;  
  16.             }  
  17.         }  
  18.         /// <summary>  
  19.         /// 执行撤销命令  
  20.         /// </summary>  
  21.         /// <param name="sender">Command</param>  
  22.         /// <param name="e">event arg</param>  
  23.         private void CommandBinding_Undo_Execute(object sender, ExecutedRoutedEventArgs e)  
  24.         {  
  25.             this.diagram.UndoManager.Undo();  
  26.         }  
  27.         /// <summary>  
  28.         /// 可否执行重做命令判断  
  29.         /// </summary>  
  30.         /// <param name="sender">Command</param>  
  31.         /// <param name="e">event arg</param>  
  32.         private void CommandBinding_Redo_CanExecute(object sender, CanExecuteRoutedEventArgs e)  
  33.         {  
  34.             if (null == this.diagram.UndoManager.History.NextRedo)  
  35.             {  
  36.                 e.CanExecute = false;  
  37.             }  
  38.             else  
  39.             {  
  40.                 e.CanExecute = true;  
  41.             }  
  42.         }  
  43.         /// <summary>  
  44.         /// 执行重做命令  
  45.         /// </summary>  
  46.         /// <param name="sender">Command</param>  
  47.         /// <param name="e">event arg</param>  
  48.         private void CommandBinding_Redo_Execute(object sender, ExecutedRoutedEventArgs e)  
  49.         {  
  50.             this.diagram.UndoManager.Redo();  
  51.         }  
  52.         /// <summary>  
  53.         /// 执行缩放命令  
  54.         /// </summary>  
  55.         /// <param name="sender">Command</param>  
  56.         /// <param name="e">event arg</param>  
  57.         private void CommandBinding_Zoom_Execute(object sender, ExecutedRoutedEventArgs e)  
  58.         {  
  59.             float zoomValue = float.Parse(e.Parameter.ToString());  
  60.             this.view.ZoomFactor = zoomValue;  
  61.             this.MenuZoomItem.Header = "缩放比例:" + zoomValue + "%"; //Hard code in here  
  62.         }  
  63.         #endregion  

 

 

有此,可以看到,使用命令大大简化了事件和方法的书写,简单明了。

而且,WPF为我们提供了大量内置命令,包括ApplicationCommands,NavigationCommands,,MediaCommands,EditingCommands与ComponentCommands,以及控件开发人员为它们的控件也提供了很多特有的命令(比如Slider.DecreaseLarge 与 Slider.DecreaseSmall),这些足以应付平时的大多数应用,如果还不够的话,你可以为自己的应用自定义更多的命令。

自定义命令需要在后台代码里定义好命令,代码如下:

 

[c-sharp] view plain copy
 
  1. #region Command  
  2.   
  3.  /// <summary>  
  4.  /// 新增流程模板分类命令  
  5.  /// </summary>  
  6.  public static readonly RoutedUICommand AddCatalog = new RoutedUICommand();  
  7.   
  8.  /// <summary>  
  9.  /// 编辑流程模板分类命令  
  10.  /// </summary>  
  11.  public static readonly RoutedUICommand EditCatalog = new RoutedUICommand();  
  12.   
  13.  /// <summary>  
  14.  /// 删除流程模板分类命令  
  15.  /// </summary>  
  16.  public static readonly RoutedUICommand DeleteCatalog = new RoutedUICommand();  
  17.  
  18.  #endregion  

 

页面代码也有所不同,代码如下:

 

[c-sharp] view plain copy
 
  1. <!--命令绑定-->  
  2. <Window.CommandBindings>  
  3.     <!-- bindings for context menu commands -->  
  4.     <CommandBinding Command="local:WorkflowManagementWindow.AddCatalog"  
  5.                     CanExecute="EvaluateCanAddCatalog"  
  6.                     Executed="ExcuteAddCatalog" />  
  7.   
  8.     <CommandBinding Command="local:WorkflowManagementWindow.EditCatalog"  
  9.                     CanExecute="EvaluateCanEditCatalog"  
  10.                     Executed="ExcuteEditCatalog" />  
  11.   
  12.     <CommandBinding Command="local:WorkflowManagementWindow.DeleteCatalog"  
  13.                     CanExecute="EvaluateCanDeleteCatalog"  
  14.                     Executed="ExcuteDeleteCatalog" />  
  15. </Window.CommandBindings>  

 

 

当然,WPF的命令系统是非常庞大和复杂的,更多的应用还需根据实际情况不断摸索。有兴趣的可以一起讨论。

posted @ 2016-10-15 11:08  天涯海角路  阅读(347)  评论(0)    收藏  举报