一、解析
一处声明,处处使用
命令四要素:
1、命令:Command,实现了ICommand接口的类;
2、命令源:CommandSource,命令发送者;
3、命令目标:CommandTarget,命令作用对象;
4、命令关联:CommandBinding,将外围逻辑与命令关联;
二、使用过程
1、创建命令类,(与逻辑无关可直接用RoutedCommand类);
2、声明命令实例:
private RoutedCommand clsCmd=new RoutedCommand("Clear",typeof(MainWindow));//声明命令实例
3、指定命令源(发送者):
btn.Command=clsCmd;//指定命令源
4、指定命令目标:
btn.CommandTarget = tbox;//指定命令目标
5、设置命令关联:
CommandBinding binding = new CommandBinding();
binding.Command=clsCmd;
binding.CanExecute += Binding_CanExecute;//添加可执行事件处理器
binding.Executed += Binding_Executed;//添加执行事件处理器
sp.CommandBindings.Add(binding);//在外围控件设置关联,用于捕获相关路由事件
注意:
- WPF自带的命令源与CommandBinding为RoutedCommand编写的(紧密联系);
- 想要实现ICommand接口派生类,必须将命令源实现(ICommandSource接口);
- ICommandSource接口有一个CommandParameter属性,用于传递信息,用于区分;
示例代码:
后台C#:
public partial class MainWindow : Window
{
private RoutedCommand clsCmd=new RoutedCommand("Clear",typeof(MainWindow));//声明命令实例
public MainWindow()
{
InitializeComponent();
btn.Command=clsCmd;//指定命令源
btn2.Command = clsCmd;
btn.CommandParameter = "Clear";
btn2.CommandParameter = "Init";
clsCmd.InputGestures.Add(new KeyGesture(Key.C, ModifierKeys.Alt));//为命令设置快捷键
btn.CommandTarget = tbox;//指定命令目标
CommandBinding binding = new CommandBinding();
binding.Command=clsCmd;
binding.CanExecute += Binding_CanExecute;//添加可执行事件处理器
binding.Executed += Binding_Executed;//添加执行事件处理器
sp.CommandBindings.Add(binding);//在外围控件设置关联,用于捕获相关路由事件
}
private void Binding_Executed(object sender, ExecutedRoutedEventArgs e)
{
if (e.Parameter.ToString() == "Clear")
{
tbox.Text = "";
}
else if (e.Parameter.ToString() == "Init")
{
tbox.Text = "Init success!";
}
}
private void Binding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
if (string.IsNullOrEmpty(tbox.Text)&&e.Parameter.ToString()=="Clear")
{
e.CanExecute = false;
}
else
{
e.CanExecute=true;
}
e.Handled = true;
}
}
前台Xaml:
<Grid x:Name="grd">
<StackPanel x:Name="sp">
<TextBox x:Name="tbox" Height="30" Background="LightBlue" Text="please Input" FontSize="20">
</TextBox>
<Button x:Name="btn" Content="Clear" Height="80" Width="80" Background="YellowGreen"/>
<Button x:Name="btn2" Content="Init" Height="80" Width="80" Background="LawnGreen"/>
</StackPanel>
</Grid>
效果图:
三、自定义命令
方式:
方式1:声明定义RoutedCommand实例,非真正意义;
方式2:实现ICommand接口,定义自己的命令并包含某些业务逻辑;
步骤:
- 声明自定义命令;
- 将命令源与命令关联;
- 将命令目标关联;
注意:
- 想要使用ICommand派生类,控件必须实现ICommandSource接口;
- 命令不会主动执行,选择合适时机去执行命令;
- 用Button填充命令源时Mouse事件会被Button“吃掉”;
- 命令声明在静态全局,供所有对象使用;
示例代码:
主窗体:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
clearCommand = new ClearCommand();
CmdSource.CommandTarget = this.tbox;
CmdSource.Command = clearCommand;
}
ClearCommand clearCommand;
}
class ClearCommand : ICommand
{
public event EventHandler CanExecuteChanged;
public bool CanExecute(object parameter)
{
throw new NotImplementedException();
}
public void Execute(object parameter)
{
TextBox textBox = parameter as TextBox;
if (textBox != null)
{
textBox.Text = "";
}
}
}
命令源控件:
public partial class MyCommandSource : UserControl,ICommandSource
{
public MyCommandSource()
{
InitializeComponent();
}
public ICommand Command { get; set; }
public object CommandParameter { get; set; }
public IInputElement CommandTarget { get; set; }
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonDown(e);
Command.Execute(CommandTarget);
}
}
<Grid>
<StackPanel>
<local:MyCommandSource x:Name="CmdSource">
<Label Width="80"
Height="80"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
Background="AntiqueWhite"
Content="Clear" />
</local:MyCommandSource>
<TextBox x:Name="tbox"
Height="30"
Background="LightBlue"
FontSize="20"
Text="hello,Auston!" />
</StackPanel>
</Grid>
点击鼠标左键前: 点击鼠标左键后: