WPF的命令Command主要解决的问题,就是代码复用。一个很重要的应用意义,在于它将很多地方需要的调用的相同操作,以统一的方式管理,却又提供了不同的访问结果。
举个例子来说,我可能通过“点击button”、“右键菜单”、“菜单栏选项”三种方式来访问同一个打印文件的方法。
相同之处:打印文件——这也是最根本的要提供的服务。
不同之处:点击button——只打印当前页;右键菜——单打印全部页;菜单栏——全部打印。
这样一个场景,既有相同、又有不同。
先说结果。
Command通过参数CommandParameter来区分不同的调用场景,提供不同的服务。
Command通过CommandBinding来绑定不同的控件需要执行的相同命令。
CommandBinding具体包括了几个要素:
1 CanExecute事件,判断命令是否可以执行,WPF会通过内部机制,自动的使能这些控件,例如button不可点击;菜单变灰等。
2 Executed事件,命令的具体逻辑
这些是命令Command的基础应用。还有两个概念:Command的source和Command的target。这些就不具体讲解了,网上很多。
下面给出具体的代码示例。
1 // MyCmds.cs 2 3 using System; 4 using System.Collections.Generic; 5 using System.Linq; 6 using System.Text; 7 using System.Threading.Tasks; 8 using System.Windows.Input; 9 10 namespace WpfApplication3 11 { 12 public class MyCmds 13 { 14 private static RoutedUICommand tcmd; 15 16 public static RoutedUICommand Tcmd 17 { 18 get { return MyCmds.tcmd; } 19 } 20 21 static MyCmds() 22 { 23 InputGestureCollection inputc = new InputGestureCollection(); 24 inputc.Add(new KeyGesture(Key.O, ModifierKeys.Control, "Ctrl+O")); 25 tcmd = new RoutedUICommand("TCmd", "TCmd", typeof(MyCmds), inputc); 26 } 27 } 28 }
1 // MainWindow.xaml 2 3 <Window x:Class="WpfApplication3.MainWindow" 4 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 5 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 6 xmlns:cmd="clr-namespace:WpfApplication3" 7 Title="MainWindow" Height="350" Width="525"> 8 <StackPanel> 9 <Menu> 10 <MenuItem Header="File"> 11 <MenuItem Command="cmd:MyCmds.Tcmd"></MenuItem> 12 </MenuItem> 13 </Menu> 14 <TextBox x:Name="txtparams" ></TextBox> 15 <Grid Height="300"> 16 <Grid.RowDefinitions> 17 <RowDefinition></RowDefinition> 18 <RowDefinition></RowDefinition> 19 </Grid.RowDefinitions> 20 <Button x:Name="click" Command="cmd:MyCmds.Tcmd" CommandParameter="{Binding ElementName=txtparams,Path=Text}" Grid.Row="0">Click</Button> 21 <Button x:Name="newbtn" Command="cmd:MyCmds.Tcmd" Grid.Row="1">newbtn</Button> 22 </Grid> 23 24 </StackPanel> 25 </Window>
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using System.Windows; 7 using System.Windows.Controls; 8 using System.Windows.Data; 9 using System.Windows.Documents; 10 using System.Windows.Input; 11 using System.Windows.Media; 12 using System.Windows.Media.Imaging; 13 using System.Windows.Navigation; 14 using System.Windows.Shapes; 15 16 namespace WpfApplication3 17 { 18 /// <summary> 19 /// MainWindow.xaml 的交互逻辑 20 /// </summary> 21 public partial class MainWindow : Window 22 { 23 public MainWindow() 24 { 25 InitializeComponent(); 26 CommandBinding binding = new CommandBinding(MyCmds.Tcmd); 27 binding.CanExecute += binding_CanExecute; 28 binding.Executed += binding_Executed; 29 this.CommandBindings.Add(binding); 30 } 31 32 void binding_CanExecute(object sender, CanExecuteRoutedEventArgs e) 33 { 34 e.CanExecute = true; 35 } 36 37 void binding_Executed(object sender, ExecutedRoutedEventArgs e) 38 { 39 if (string.IsNullOrEmpty((string)e.Parameter)) 40 { 41 MessageBox.Show("hello cmds"); 42 } 43 else if (e.Parameter.ToString() == "lib") 44 { 45 MessageBox.Show("lib"); 46 } 47 else if (e.Parameter.ToString() == "com") 48 { 49 MessageBox.Show("com"); 50 } 51 else 52 { 53 MessageBox.Show("stupid"); 54 } 55 } 56 } 57 }