9.2 近观命令
9.2.1 ICommand接口与RoutedCommand
Execute方法:命令执行,或者说命令作用于命令目标之上。
CanExecute方法:在执行之前用来探知命令是否可被执行。
CanExecuteChanged事件:当命令可执行状态发生改变时,可激发此事件来通知其他对象。
9.2.2 自定义Command
public class ClearTextBoxCommand : ICommand
{
public bool CanExecute(object parameter)
{
TextBox param = parameter as TextBox;
if (param == null)
return true;
if (!string.IsNullOrEmpty(param.Text))
return true;
else
return false;
}
public event EventHandler CanExecuteChanged;
public void Execute(object parameter)
{
TextBox param = parameter as TextBox;
param.Text = string.Empty;
}
}
<Window x:Class="WpfApplication8.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:proj="clr-namespace:WpfApplication8"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<proj:ClearTextBoxCommand x:Key="comm" />
</Window.Resources>
<StackPanel>
<TextBox Height="23" Name="textBox1" VerticalAlignment="Top" Width="120" Margin="5"/>
<Button Name="button1" Content="Button" Width="75"
Command="{StaticResource comm}" CommandParameter="{Binding ElementName=textBox1}" >
</Button>
</StackPanel>
</Window>
注意,这里没有定义CommandBinding与CommandTarget
另外一种方式:
public class ClearTextBoxCommand : RoutedCommand
{}
注意这里继承自RoutedCommand类
<Window x:Class="WpfApplication8.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:proj="clr-namespace:WpfApplication8"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<proj:ClearTextBoxCommand x:Key="comm" />
</Window.Resources>
<StackPanel>
<StackPanel.CommandBindings>
<CommandBinding Command="{StaticResource comm}" Executed="CommandBinding_Executed" CanExecute="CommandBinding_CanExecute" />
</StackPanel.CommandBindings>
<TextBox Height="23" Name="textBox1" VerticalAlignment="Top" Width="120" Margin="5"/>
<Button Name="button1" Content="Button" Width="75"
Command="{StaticResource comm}" CommandParameter="{Binding ElementName=textBox1}" CommandTarget="{Binding ElementName=textBox1}" >
</Button>
</StackPanel>
</Window>
注意这里定义了CommandTarget,以路由事件的方式调用 public void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
TextBox param = e.Parameter as TextBox;
if (param == null)
{
e.CanExecute = true;
e.Handled = true;
}
else
{
if (!string.IsNullOrEmpty(param.Text))
e.CanExecute = true;
else
e.CanExecute = false;
e.Handled = true;
}
}
public void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
{
TextBox param = e.Parameter as TextBox;
param.Text = string.Empty;
e.Handled = true;
}
个人感觉Microsoft在Command这块,基于ICommand接口搞了一套调用机制,基于RoutedCommand类又搞了一套调用机制,而且RoutedCommand私有继承隐藏了ICommand的方法,感觉很乱。
如果自定义的Command直接继承自ICommand,那用起来比较简单,如第一个例子。
如果自定义的Command继承自RoutedCommand,那需要在Target控件的Virtual Tree上层的控件中定义该Command的CommandBinding,而且需要设置CommandTarget来从Target控件处RaiseEvent,如第二个例子。