事件不具有约束力,命令与事件的区别就在于命令具有约束力。
命令的使用大概分为以下几步:
(1)、创建命令类:即获得一个实现ICommand接口的类,如果命令与具体业务逻辑无关则使用WPF类库中的RoutedCommand类即可。如果与业务逻辑相关的专有命令,则需要创建RoutedCommand(或者ICommand接口)的派生类。
(2)、声明命令实例:使用命令时需要创建命令类的实例。使用技巧,一般情况下程序中某种操作只需要一个命令实例与之对应即可。比如对应“保存”这个操作,你可以拿一个实例去命令每个组件执行其保存功能,因此程序中的命令多使用单件模式(Singletone Pattern)以减少代码的复杂度。
(3)、指定命令的源:即指定由谁来发送这个命令。同一个命令可以有多个源。
(4)、指定命令目标:命令目标不是命令 的属性而是命令源的属性,指定命令目标是告诉命令源向哪个组件发送命令。如果没有为命令源指定命令目标,则WPF系统认为当前拥有焦点的对象就是命令目标。
(5)、设置命令关联:WPF命令需要CommandBinding在执行前来帮助判断是不是可以执行、在执行后做一些事件来“打扫战场“。
WPF命令系统基本元素的关系图如下:
下面看一个例子:
实现这样一个需求:定义一个命令,使用Button来发送这个命令,当命令送达TextBox时TextBox会被清空(无文本不被发送)。
XAML界面代码如下:
<Window x:Class="WpfWindows8.WinMain9_1_3"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfWindows8"
mc:Ignorable="d"
Title="Command" Background="LightBlue" Height="175" Width="260">
<StackPanel x:Name="stackPanel">
<Button x:Name="btn1" Content="Send Command" Margin="5" />
<TextBox x:Name="txtBoxA" Margin="5, 0" Height="100" />
</StackPanel>
</Window>
后台代码为:
//声明并定义命令
private RoutedCommand clearCmd = new RoutedCommand("Clear", typeof(WinMain9_1_3));
public WinMain9_1_3()
{
InitializeComponent();
InitializeCommand();
}
private void InitializeCommand()
{
//把命令赋值给命令源(发送者)并制定快捷键
this.btn1.Command = this.clearCmd;
this.clearCmd.InputGestures.Add(new KeyGesture(Key.C, ModifierKeys.Alt));
//指定命令目标
this.btn1.CommandTarget = this.txtBoxA;
//创建命令关联
CommandBinding cb = new CommandBinding();
cb.Command = this.clearCmd; //只关注与clearCmd相关的事件
cb.CanExecute += new CanExecuteRoutedEventHandler(cb_CanExecute);
cb.Executed += new ExecutedRoutedEventHandler(cb_Executed);
//把命令关联安置在外围控件上
this.stackPanel.CommandBindings.Add(cb);
}
//当命令送达目标后,此方法被调用
private void cb_Executed(object sender, ExecutedRoutedEventArgs e)
{
this.txtBoxA.Clear();
//避免继续向上传而减低程序性能
e.Handled = true;
}
//当探测命令是否可以执行时,此方法被调用
private void cb_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
if (string.IsNullOrEmpty(this.txtBoxA.Text))
{
e.CanExecute = false;
}
else
{
e.CanExecute = true;
}
//避免继续向上传而降低程序性能
e.Handled = true;
}
运行程序,在TextBox中输入文字后Button在命令可以行状态的影响下变为可用,此时单机Button或者按Alr+C,TextBox都会被清空,效果如下图: