一个Button,如下

<WrapPanel>
<Button Content="Button" Click="Button_Click" />
</WrapPanel>


 

private void Button_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Hello World");
}


没啥问题.

业务与UI分离

这个是我们一致想到达到了,所以不想在Click事件里写东西,换成了一个Command

自定义ICommand
public partial class Window3 : Window
{
public Window3()
{
InitializeComponent();
btn.Command = new MyCommand();
}

//private void Button_Click(object sender, RoutedEventArgs e)
//{
// MessageBox.Show("Hello World");
//}
}

public class MyCommand : ICommand
{
public bool CanExecute(object parameter)
{
return true;
}

public event EventHandler CanExecuteChanged;

public void Execute(object parameter)
{
MessageBox.Show("Hello World");
}
}


现在把逻辑分离到MyCommand 里了

预设置命令

如ApplicationCommands.Close之类的命令

​​WPF Command_ide​​

从第一眼看到的时候就特高兴,感觉有这么多封装好的东西,可惜这只是预设置命令而已,根本就没有实现.如下

<Button Content="Button" x:Name="btn" Command="ApplicationCommands.Close"/>


​​WPF Command_自定义_02​​

可以看到命令根本没有实现

使用CommandBindings添加命令逻辑
public Window3()
{
InitializeComponent();

var OpenCmdBinding = new CommandBinding(
ApplicationCommands.Close,
OpenCmdExecuted,
OpenCmdCanExecute);

this.CommandBindings.Add(OpenCmdBinding);
}

void OpenCmdExecuted(object target, ExecutedRoutedEventArgs e)
{
this.Close();
}

void OpenCmdCanExecute(object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}


以上就算是实现了

ICommandSource

并非所有控件都有Command属性的,如下图

​​WPF Command_ico_03​​

CommandParameter即可以给命令传递一个值

CommandTarget:触发的命令目标

若Slider控件吧,Value可以增加也可以减少,如下代码

<Button  Content="Increase"  x:Name="btn"  Command="Slider.IncreaseLarge"  CommandTarget="{Binding  ElementName=slider}"/>
<Button Content="Decrease" Command="Slider.DecreaseLarge" CommandTarget="{Binding ElementName=slider}"/>
<Slider x:Name="slider" Width="100"></Slider>
<Slider x:Name="slider2" Width="100"></Slider>


 

自定义RoutedCommand    

如上面的Slider一样,给控件预定义命令,并实现它,可使用​​CommandManager​

​​WPF Command_ide_04​​

到这里可以又可以看到CommandBinding的影子

RoutedCommand是与UI集合在一起的,而ICommand则纯逻辑性的,本质上Command也是通过内置的事件封装引发的,只是加了一层皮,去掉了事件的影子而已,毕竟基于WPF,使用纯粹的ICommand有时候并无法满足所有的需求。