zoukankan      html  css  js  c++  java
  • WPF自定义命令

     

      在实际的编程工作中,我们可以只是用事件,不用命令,程序的逻辑也一样被驱动的很好,但我们不能阻止程序员按照自己的习惯去写代码。比如保存事件的处理器,程序员们可以写Save()、Savehandler()、SaveDocument()...这些都符合代码规范,但是迟早有一天整个项目会变得无法读懂,新来的程序员或者修改bug的程序员会很抓狂。

    WPF命令简介       

    WPF的命令是实现了ICommand接口的类。ICommand接口非常简单,只包含两个方法和一个事件。

    • Execute方法:命令执行,或者说命令作用于目标之上。
    • CanExecute方法:在执行之前来弹指命令是否可被执行。
    • CanExecuteChanged事件:当命令执行状态发生改变时,可激发此事件来通知其他对象。

    RoutedCommand就是这样一个实现了ICommand接口的类。RoutedCommand在实现ICommand接口时,并未向其中添加任何逻辑。

    WPF的命令系统由几个基本元素构成,他们是:

    • 命令:WPF命令实际上就是实现了ICommand接口的类,平时使用最多的是RoutedCommand类。
    • 命令源:即命令的发送者,是实现了ICommandSource接口的类。
    • 命令目标:即命令将推送给谁,或者说命令将作用在谁身上。命令目标是必须实现了IInputElement接口的类。
    • 命令关联:负责把一些外围逻辑与命令关联起来,比如执行之前对命令是否可执行进行判断、命令执行后还有那些后续工作等。

     命令具有一处声明处处可用的特点,因此,MS在WPF类库里准备而来一些便捷的命令库,例如:

    下面分别用WPF命令库,和自定义命令实现同样的功能。

    WPF命令库命令   

    Demo程序的UI如下:

    复制代码
    <Window x:Class="WPFCommand.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="MainWindow" Height="350" Width="525">
        <Window.CommandBindings>
            <CommandBinding Command="New" CanExecute="CommandBinding_CanExecute" Executed="CommandBinding_Executed"/>
        </Window.CommandBindings>
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <DockPanel Height="60" Grid.Row="0">
                <TextBlock VerticalAlignment="Center"  Text="Name:" DockPanel.Dock="Left"  Width="100" FontSize="30" Foreground="PaleVioletRed"/>
                <TextBox x:Name="txtName" DockPanel.Dock="Right"  FontSize="40"/>
            </DockPanel>
            <Button Command="New" CommandParameter="Teacher" Content="New Teacher" Grid.Row ="1"/>
            <Button Command="New" CommandParameter="Student" Content="New Student" Grid.Row ="2"/>
            <ListBox x:Name="listBox1" Grid.Row="3" Grid.RowSpan="2"/>
        </Grid>
    </Window>
    复制代码

    后台代码如下:

    复制代码
    using System.Windows;
    using System.Windows.Input;
    
    namespace WPFCommand
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private void CommandBinding_CanExecute(object sender, CanExecuteRoutedEventArgs e)
            {
                if (string.IsNullOrWhiteSpace(txtName.Text))
                {
                    e.CanExecute = false;
                }
                else
                {
                    e.CanExecute = true;
                }
            }
    
            private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
            {
                string name = txtName.Text;
                if (e.Parameter.ToString() == "Teacher")
                {
                    listBox1.Items.Add("New Teacher: "+name);
                }
                if (e.Parameter.ToString() == "Student")
                {
                    listBox1.Items.Add("New Student: "+name);
                }
            }
        }
    }
    复制代码

    程序的运行结果如下:

    当txtName.Text为WhiteSpace时,命令不可被执行。

    执行后效果如下:

    前面说过不用命令,程序的逻辑也可以被驱动的很好。且在一般情况下,在程序中使用与逻辑无关的RoutedCommand来跑跑龙套也就足够了,上面这个命令用的就有十足的“酱油”的嫌疑。

     OK,把打酱油进行到底吧,下面自定义一个命令,实现相同的功能。

    WPF自定义命令    

    注意对比前面使用命令库命令的方法异同。

    程序的UI如下:

    复制代码
    <Window x:Class="MyCommand.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="My Command Window" Height="350" Width="525" x:Name="mainWindow" >
        <Grid >
            <Grid.RowDefinitions>
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
                <RowDefinition />
            </Grid.RowDefinitions>
            <DockPanel Height="60" Grid.Row="0">
                <TextBlock VerticalAlignment="Center"  Text="Name:" DockPanel.Dock="Left"  Width="100" FontSize="30" Foreground="PaleVioletRed"/>
                <TextBox x:Name="txtName" DockPanel.Dock="Right"  FontSize="40"/>
            </DockPanel>
            <Button  CommandParameter="Teacher"  x:Name="button1" Content="New Teacher" Grid.Row ="1"/>
            <Button  CommandParameter="Student"  x:Name="button2" Content="New Student" Grid.Row ="2"/>
            <ListBox x:Name="listBox1" Grid.Row="3" Grid.RowSpan="2"/>
        </Grid>
    </Window>
    复制代码

    后台代码如下:

    复制代码
    using System.Windows;
    using System.Windows.Input;
    
    namespace MyCommand
    {
        /// <summary>
        /// MainWindow.xaml 的交互逻辑
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
                //
                InitCmd();
            }
    
            //声明并定义命令
            private RoutedCommand newCmd=new RoutedCommand ("NewTS",typeof(MainWindow ));
    
            private void InitCmd()
            {            
                //创建命令关联
                CommandBinding cb = new CommandBinding();
                cb.Command = newCmd;
                cb.CanExecute += new CanExecuteRoutedEventHandler(CanExecute1);
                cb.Executed += new ExecutedRoutedEventHandler(Executed1);
                //把命令关联安置在外围控件上
                mainWindow.CommandBindings.Add(cb);
    
                //把命令赋值给命令源(发送者)
                button1.Command = newCmd;
                button2.Command = newCmd;
            }
    
            private void CanExecute1(object sender,CanExecuteRoutedEventArgs e)
            {
                //e.CanExecute = true;
                if (string.IsNullOrWhiteSpace(txtName.Text))
                {
                    e.CanExecute = false;
                }
                else
                {
                    e.CanExecute = true;
                }
            }
    
            private void Executed1(object sender, ExecutedRoutedEventArgs e)
            {
                string name = txtName.Text;
                if (e.Parameter.ToString() == "Teacher")
                {
                    listBox1.Items.Add("New Teacher: " + name);
                }
                if (e.Parameter.ToString() == "Student")
                {
                    listBox1.Items.Add("New Student: " + name);
                }
            }
        }
    }
    复制代码

    程序的运行效果和上面的相同: 

    当txtName.Text为WhiteSpace时,命令不可被执行。

    执行后效果如下:

  • 相关阅读:
    suse10+samba+ldap搭建pdc备忘
    深入挖掘Windows脚本技术(转自http://www.yuanma.org/data/2006/1212/article_1935.htm)
    Getting Paging working with Mitel Phones
    CentOS4.4+Samba+LDAP备忘
    oracle字符集问题
    Trixbox(Asterisk)+sangoma A101D+PBX
    Some useful vba macros
    (转载)wipe.c and z2.c
    Trixbox2.2+webmeetme2.2
    (转载)hosts.equiv和.rhosts文件
  • 原文地址:https://www.cnblogs.com/changbaishan/p/3616396.html
Copyright © 2011-2022 走看看