(七)命令

来源:互联网 发布:医疗大数据国内外现状 编辑:程序博客网 时间:2024/06/11 05:10

命令使用步骤:

  • 创建命令类,即获得实现ICommand接口的一个类,创建RoutedCommand(与业务无关)或者其(或ICommand)的派生类(与业务有关)。
  • 声明命令实例
  • 指定命令源,即指定由谁来发命令,同一个命令可以有多个命令源。当吧命令指派给命令源的时候,命令源的使用会受到命令的影响。当命令不可用的时候,命令源的空件处于不可用状态。
  • 指定命令目标。命令目标不是命令的属性,而是命令源的属性。指定命令目标是告诉命令源向哪个组件发命令。无论这个组件是否有交点,它都会收到这个命令。若没有指定命令目标,则wpf系统认为当前拥有焦点的对象就是命令目标。
  • 设置命令关联,wpf命令需要CommandBinding在执行前来帮助判断是否可以执行。在执行后做一些事。

下面进行介绍命令系统基本元素的关系图:

这里写图片描述

命令源是命令的拥有者,命令反过来影响命令源状态

命令源用于命令目标,并且,命令源会一直向命令目标发消息。

命令目标然后会发送出可路由的事件(PreviewCanExecyte与CanExecute)

命令关联捕捉到这些事件后把命令能否发送实时的报告给命令。

一旦某个UI组件被命令源“瞄上”,命令源就会不断地向命令目标“投石问路”,命令目标就不停地发送可路由的PreviewCanExecyte与CanExecute附加事件,事件会沿着UI树向上传递并被命令关联所捕捉。命令关联捕捉到这些事件后会把命令能否发送实时报告给命令。类似的命令被发送出来到达命令目标,命令目标就会发送PreviewExecuteed和Executed两个附件事件,这两个事件也会随着Ui元素树向上传递并被命令关联所捕获,命令关联去完成一些后续的任务。

命令示例一

Xaml界面

<StackPanel x:Name="stackPanel">       <Button x:Name="Button1" Content="SendCommand" Margin="5"/>       <TextBox x:Name="TextBoxA" Margin="5,0" Height="100"/></StackPanel>

按照流程实现一个命令

 public partial class MainWindow : Window    {        public MainWindow()        {            InitializeComponent();            InitializeCommand();        }        //定义命令        private RoutedCommand clearCmd = new RoutedCommand("Clear",typeof(MainWindow));        private void InitializeCommand()        {            // 命令赋值给命令源 指定快捷键            this.Button1.Command = this.clearCmd;            this.clearCmd.InputGestures.Add(new KeyGesture(Key.C, ModifierKeys.Alt));            //指定命令目标            this.Button1.CommandTarget = this.TextBoxA;            //创建设置命令关联            CommandBinding cb = new CommandBinding();            cb.Command = this.clearCmd;            cb.CanExecute+=new CanExecuteRoutedEventHandler(cb_CanExecute);            cb.Executed += new ExecutedRoutedEventHandler(cb_Executed);            //将命令关联设置在textbox控件上            this.TextBoxA.CommandBindings.Add(cb);            //this.stackPanel.CommandBindings(cb);这样也可以。        }       //当命令送达目标后执行        private void cb_Executed(object sender, ExecutedRoutedEventArgs e)        {            this.TextBoxA.Clear();            e.Handled = true; //避免继续向上传        }        //检测命令是否可以执行时执行。        private void cb_CanExecute(object sender, CanExecuteRoutedEventArgs e)        {            if (string.IsNullOrEmpty(this.TextBoxA.Text))            {                e.CanExecute = false;            }            else            {                e.CanExecute = true;            }            e.Handled = true;//避免向上传影响性能。        }    }}

对于上面的代码进行解释
- 命令在这里没有进行任何操作,只负责“跑腿”。

  • 对Text清理操作是由CommandBinding完成。在上面的例子中CommandBind捕捉到Executed事件就会调用cb_Executed。当捕捉到CanExecute事件则会反馈给命令源,影响命令源的状态。
  • CanExecuted事件的触发频率高,为了性能处理完后e.Handled设置为true隔断传播。
    #### 结果:
    这里写图片描述

带命令参数的示例

命令库里有好多Wpf的预制命令,(New,Open,Save…)这些命令是类的静态属性因此他们的实例只能有一个。这时就会有一个问题:如果由两个按钮都使用同一个命令,他们完成的任务不同,此时该怎么去分?下面示例进行解决这个问题:

<Grid Margin="6">        <Grid.RowDefinitions>            <RowDefinition Height="24"/>            <RowDefinition Height="4"/>            <RowDefinition Height="24"/>            <RowDefinition Height="4"/>            <RowDefinition Height="24"/>            <RowDefinition Height="4"/>            <RowDefinition Height="*"/>        </Grid.RowDefinitions>        <TextBlock Text="Name:" VerticalAlignment="Center" HorizontalAlignment="Left" Grid.Row="0"></TextBlock>        <TextBox x:Name="nameTextBox" Margin="60,0,0,0" Grid.Row="0"></TextBox>        <Button Name ="button1"  Content="New Teacher"  Command="ApplicationCommands.New" CommandParameter="Teacher" Grid.Row="2"/>        <Button Name="button2" Content="New Student" Command="ApplicationCommands.New" CommandParameter="Student" Grid.Row="4"/>        <ListBox x:Name="listBoxNewItems" Grid.Row="6"></ListBox></Grid><Window.CommandBindings>        <CommandBinding  Command="ApplicationCommands.New"  CanExecute="New_CanExecute" Executed="New_Execute"/></Window.CommandBindings>

对应的cs代码

public partial class MainWindow : Window    {        public MainWindow()        {            InitializeComponent();        }        private void New_CanExecute(object sender, CanExecuteRoutedEventArgs e)        {           if (string.IsNullOrEmpty(this.nameTextBox.Text))            {                e.CanExecute = false;            }            else            {                e.CanExecute = true;            }        }        private void New_Execute(object sender, ExecutedRoutedEventArgs e)        {            string name = this.nameTextBox.Text;            if (e.Parameter.ToString() == "Teacher")            {                this.listBoxNewItems.Items.Add(string.Format($"New Teacher:{name}"));            }            if (e.Parameter.ToString() == "Student")            {                this.listBoxNewItems.Items.Add(string.Format($"New Student:{name}"));            }        }    }

运行结果:

这里写图片描述

原创粉丝点击