首先,谈一下Menu菜单的Commad
<DockPanel>
<Menu DockPanel.Dock="Top">
<MenuItem Command="ApplicationCommands.Copy" Width="75" />
</Menu>
<TextBox BorderBrush="Black" BorderThickness="2" Margin="25"
TextWrapping="Wrap">
The MenuItem will not be enabled until
this TextBox gets keyboard focus
</TextBox>
</DockPanel>
通过利用内置的ApplicationCommands的命令,直接设置MenuItem的Command属性,而且不需要设置CommandTarget,默认是获取有焦点的控件,Copy命令如果有选中的文字则菜单可用;Paste命令是只要剪贴板有文字内容,且目前获取焦点的控件可以输入文本,菜单就可用。(内置命令的功能,不需要额外代码)
如果在Button上使用ApplicationCommands的命令,则效果和Menu是不一样的。
Paste命令
1.有CommandTarget
<TextBox Name="txtCmd" Width="100" Height="31"/>
<Button Name="btnCmd" Width="89" Height="31"
Command="Paste" CommandTarget="{Binding ElementName=txtCmd}"/>
此时,只要剪贴板有文字内容,则Button可用,单击Button会将内容Paste到TextBox中(TextBox不需要获得焦点)
2.无CommandTarget
<TextBox Name="txtCmd" Width="100" Height="31"/>
<Button Name="btnCmd" Width="89" Height="31"
Command="Paste" />
此时,Button一直不可用,即使TextBox获取焦点。
得出的结论是:
Button的Paste命令和Menu的命令实现不同,Button需要CommandTarget才可以Paste,而Menu只需要获取焦点的控件能进行输入就能Paste。
Copy命令
1.有CommandTarget
<TextBox Name="txtCmd" Width="100" Height="31"/>
<Button Name="btnCmd" Width="89" Height="31"
Command="Copy" CommandTarget="{Binding ElementName=txtCmd}"/>
此时,TextBox中需要有内容且要有选中的文字,Button才可用,当单击Button的时候,选中的文字就被Copy下来了,有些人(包括我)可能会发现单击Button的时候,TextBox中选中的文字背景颜色会消失(以为此时没有选中的文字,但是Button还是可用,迷惑。。。),其实这是因为TextBox失去焦点了,选中的文字还是被选中的,可以通过给Button添加Click事件,在事件中查看txtCmd.SelectedText的值或者也可以按Tab键让焦点再次回到TextBox中,反正方法还是比较多的。
2.无CommandTarget
<TextBox Name="txtCmd" Width="100" Height="31"/>
<Button Name="btnCmd" Width="89" Height="31"
Command="Copy"/>
此时,不管TextBox中是否有文字,且文字被选中,Button一直不可用。
当Button使用的命令是内置命令的时候(目前只用过ApplicationCommands),如果没有设置CommandTarget时,可以实现自己的逻辑(假如Command为Copy时,你可以不实现Copy功能,而实现删除操作也可以,视具体需求而定)
例如:
以下代码当txtCmd有值时,Button就可用(跟Copy命令就不一样了),加了个e.Handled = true,是因为cb_CanExecute执行频率比较高,为了避免降低性能,处理完了就停止向上冒泡。这段代码最后实现了Copy命令,只是简单的弹了个文本消息“Hi Command”。
<TextBox Name="txtCmd" Width="100" Height="31"/>
<Button Name="btnCmd" Width="89" Height="31"
Command="Copy"/>
CommandBinding cb = new CommandBinding();
cb.Command = ApplicationCommands.Copy;
cb.CanExecute += cb_CanExecute;
cb.Executed += cb_Executed;
this.CommandBindings.Add(cb);
void cb_Executed(object sender, ExecutedRoutedEventArgs e)
{
MessageBox.Show("Hi Command");
e.Handled = true;
}
void cb_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
if (string.IsNullOrEmpty(txtCmd.Text))
{
e.CanExecute = false;
}
else
{
e.CanExecute = true;
}
e.Handled = true;
}
最后的结论是,Button实现内置命令的时候,如果没有设置CommandTarget,则Button一直是不可用的,除非通过上级容器捕获Button的命令,再通过CanExecute和Executed事件实现自己的逻辑。