关于Command

巫马刚洁
2023-12-01

首先,谈一下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事件实现自己的逻辑。



 类似资料: