WPF命令(Command)介绍、命令和数据绑定集成应用

要开始使用命令,必须做三件事:

                                              一:定义一个命令

                                              二:定义命令的实现

                                              三:为命令创建一个触发器

    WPF中命令系统的基础是一个相对简单的ICommand的接口,代码如下:

public interface ICommand {
 event EventHandler CanExecuteChanged;
 bool CanExecute(object parameter);
 void Execute(object parameter);
}

 

       CanExecute用于确定命令是否处于可执行的状态。典型的,UI控件能使用CanExecute来启用或禁用自己。也就是说,在相关的命令从CanExecute中返回False的时候,按钮将变得不可用。

      Execute是命令的关键,当被调用时,它将触发命令的执行。

      要定义一个新命令,可以实现ICommand接口。如希望ICommand在被调用后关闭应用程序,代码如下:

 

public class Exit : ICommand {
 event EventHandler CanExecuteChanged;
 public bool CanExecute(object parameter)
{
 return true;
}
public void Execute(object parameter)
 {
Application.Current.Shutdown();
}
}

 


    要把一个菜单项绑定到应用程序关闭这个命令上,可以把他们的Command属性挂到Exit命令上,代码如下:

 

<MenuItem Header="_File">
 <MenuItem Header="_Exit">
 <MenuItem.Command>
 <local:Exit/>
</MenuItem.Command>
 </MenuItem>
</MenuItem>

 

 

由于把命令用于多个位置比较常见,所以创建一个存储命令的静态字段也常见:

 

public static readonly ICommand ExitCommand = new Exit();

 

这样做的好处是,通过这个类型为ICommand的字段,可以让Exit命令的实现完全私有化。现在,可以把Exit标记为私有类,并把标记转化为绑定到静态字段,代码如下:

 

        <MenuItem Header="_File">
            <MenuItem Header="_Exit" Command="{x:Static local:WinCommand.ExitCommand}"/>
        </MenuItem>

 

下面我们通过添加一个和Close命令挂接的按钮,可以为窗口编写一个模板,以实现关闭窗口的功能,代码如下:

 

 <Window.Style>
        <Style TargetType="Window">

            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate  TargetType="Window">
                        <DockPanel>
                            <StatusBar DockPanel.Dock="Bottom">
                                <StatusBarItem>
                                    <Button
                            Command="{x:Static ApplicationCommands.Close}">Close</Button>
                                </StatusBarItem>
                            </StatusBar>
                            <ContentPresenter/>
                        </DockPanel>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Style>

 

 

我们接着要通过把命令绑定添加到窗口中让窗口关闭。

 

  /// <summary>
    /// WinCommand.xaml 的交互逻辑
    /// </summary>
    public partial class WinCommand : Window
    {
        public static readonly ICommand ExitCommand = new Exit();
        public WinCommand()
        {
            InitializeComponent();

            CommandBindings.Add(
                new CommandBinding(
                    ApplicationCommands.Close,
                    CloseExecuted));

        }

        void CloseExecuted(object sender, ExecutedRoutedEventArgs e)
        {
            this.Close();
        }

    }

 

 

使用命令可以清晰地把显示和行为分开。通过使用单一的名称为所需的语义动作签名,在尝试把多个控件和单个事件处理过程挂接起来的时候,可以避免很多由此引发的紧耦合问题。通常,应用程序逻辑应该总是通过命令的方式来实现的,而不是事件处理程序。对于很多需要直接挂接到事件处理过程上的常见例子,用触发器来处理更好。

命令与数据绑定

 

          使用命令的一个令人振奋和强大的特性 就是和数据绑定集成。由于Command和CommandParameter都是元素上的属性,所以他们都能被设置为一些绑定到他们的数据。因此,可以使用绑定的数据内容来确定应该发生的动作。

      为了演示他们是如何融合到一起的,将以C:\下面的文件的应用程序来开头。首先,定义一个显示内容的ListBox,和一个显示了每个文件名的数据模板,代码如下:

<ListBox Margin="2" Name="lbFile">

<ListBox.ItemTemplate>

<DataTemplate>

<TextBlock Text="{Binding Path=Name}"/>

</DataTemplate>

</ListBox.ItemTemplate>

</ListBox>

 

在后台,把ItemSource属性设置为文件列表:


public WinCommandAndBinding()
{
 InitializeComponent();

 FileInfo[] fileList = new DirectoryInfo("C:\\").GetFiles("*.*");

lbFile.ItemsSource = fileList;
 }

 

运行如下:

现在,再添加一个按钮用来显示文件,但不希望任何文件都被打开。所以,要在加载的文件上提供某种类型的过滤器。现实现两个命令Open和Blocked并为他们提供某种类型的处理过程,代码如下:

  public static readonly RoutedCommand OpenCommand =
            new RoutedCommand("Open", typeof(WinCommandAndBinding));

        public static readonly RoutedCommand BlockedCommand =
            new RoutedCommand("Blocked", typeof(WinCommandAndBinding));

        public WinCommandAndBinding()
        {
            InitializeComponent();

            CommandBindings.Add(new CommandBinding (OpenCommand,
                delegate(object sender,ExecutedRoutedEventArgs e){
                    Process.Start("notepad.exe",(string)e.Parameter);}));

            CommandBindings.Add(new CommandBinding(BlockedCommand,
                delegate(object sender, ExecutedRoutedEventArgs e)
                {
                    MessageBox.Show((string)e.Parameter, "Blocked");
                }));

            FileInfo[] fileList = new DirectoryInfo("C:\\").GetFiles("*.*");
            lbFile.ItemsSource = fileList;
        }
    }

 

在定义好两个命令后,就可以更新文件的数据模板来包含按钮了。在命令参数(文件名)中使用数据绑定。对应命令本身,由于希望某些条目用OpenCommand,而其他条目用BlockedCommand,所以将使用IValueConvert把文件名转换为ICommand,代码如下:

 

 <ListBox Margin="2" Name="lbFile">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <WrapPanel>
                        <TextBlock Text="{Binding Path=Name}"/>
                        <Button Margin="5" CommandParameter="{Binding Path=FullName}">
                            <Button.Command>
                                <Binding>
                                    <Binding.Converter>
                                        <local:FileToCommandConverter/>
                                    </Binding.Converter>
                                </Binding>
                            </Button.Command> Show
                        </Button>
                    </WrapPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

 

 

 

下面是转换器:

 

    public class FileToCommandConverter : IValueConverter
    {
        public object Convert(object value ,Type targetType,object parameter,CultureInfo culture)
        {
            string ext = ((FileInfo)value).Extension.ToLowerInvariant();
            if (ext == ".txt")
                return WinCommandAndBinding.OpenCommand;
            else
                return WinCommandAndBinding.BlockedCommand;
        }
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

 

 

 

运行结果:

这个例子虽然有点微不足道,不过可以使用CanExecute方法轻松地完成类似的行为,并针对“坏”文件禁用这个命令。然而,这里最重要的一点是,可以返回任何命令。可以使用任何基于数据的逻辑来确定任何元素的行为。

另外我们可以考虑下能不能用数据触发器实现呢?呵呵,可以的,这等于把命令、数据绑定和触发器三者融合到一起了?是不是很强大,呵呵下面是代码:

 

 <ListBox Margin="2" Name="lbFile2">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <WrapPanel>
                        <TextBlock Text="{Binding Path=Name}"/>
                        <Button x:Name="btnShow" Margin="5" CommandParameter="{Binding Path=FullName}"
                                Command="{x:Static local:WinCommandAndBinding.BlockedCommand}"
                                Content="  Block"/>
                    </WrapPanel>
                    <DataTemplate.Triggers>
                        <DataTrigger  Value=".txt">
                            <DataTrigger.Binding>
                                <Binding  Path='Extension'>
                                    <Binding.Converter>
                                        <local:ToLowerInvariantConvert/>
                                    </Binding.Converter>
                                </Binding>
                            </DataTrigger.Binding>
                            <Setter TargetName="btnShow"
                            Property="Command"
                                Value="{x:Static local:WinCommandAndBinding.OpenCommand}"/>
                            <Setter TargetName="btnShow" Property="Content" Value="Show"/>
                        </DataTrigger>
                    </DataTemplate.Triggers>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

 

 

 


转换器:
    public class ToLowerInvariantConvert : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
          return  ((string)value).ToLowerInvariant();

        }
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

 

如果感觉不错的话,请帮忙推荐,谢谢……

时间: 2024-10-06 14:22:09

WPF命令(Command)介绍、命令和数据绑定集成应用的相关文章

《Ansible权威指南 》一3.2 Ad-Hoc命令集介绍

3.2 Ad-Hoc命令集介绍 本节介绍通过Ad-Hoc命令集查看系统设置,通过Ad-Hoc研究Ansible的并发特性,通过Ad-Hoc研究Ansible的模块使用.俗话说,磨刀不误砍柴工.开始之前做一些简单的初始化检查,如系统时间正确与否.磁盘容量是否充足等,是很有必要的. 在实际工作中,很多"诡异"问题迫使我们花费大量时间排查,最终却发现是非常简单的基础环境问题导致的.这其实还是挺常见的,不论对新手还是老鸟均如此,谨记! 我们前面做的系统时间正确与否.磁盘容量是否充足等工作,其实

Linux系统中top命令详细介绍

后面会介绍一些linux中常用的运维命令,利用这些命令我们能够迅速的定位问题所在,并解决问题.今天先从最常见的开始-TOP命令. 命令含义介绍 运行top命令之后,会出现如下内容 top - 03:37:17 up 32 min,  2 users,  load average: 0.00, 0.00, 0.00 Tasks:  10 total,   1 running,   9 sleeping,   0 stopped,   0 zombie %Cpu(s):  0.0 us,  0.0

Flash中拖拽命令详细介绍

注:以下教程均是在Flash MX 2004版本下进行! 在网上经常看到的flash影片中有的对象可以被鼠标进行拖动.例如有的类似七巧板的拼图游戏,控制音量的滑杆等,所使用的就是flash中的拖拽动作.最近在论坛有人询问讲解一下鼠标拖拽效果的实现方法,今天从网上找了几篇文章综合了下给大家讲解一下! 下面我来讲解一下拖拽命令. 1.首先介绍一下开始拖拽命令的详细用法,稍后在后面的例子中进行测试. 命令格式:StartDrag(要拖动的影片剪辑,[是否锁定到鼠标位置中央,左,上,右,下])或写为要拖

基本UNIX命令集介绍

UNIX命令集是很有特色的命令集.它被设计成用来全面控制UNIX的机器.这部分将对UNIX命令集的一部分进行讨论.本部分与后面重点讲述经常用于传输控制协议(TCP)和Internet协议(IP)的UNIX命令.请注意我们要讨论的仅是UNIX中最常用的命令而不是对它的命令作一通览.后面每一部分都对命令集的一个命令进行介绍.在本章的最后,您还会学到黑客们经常用来侵入服务器的命令. 1.匹配符 在谈到命令时,如果该命令对应的文件不在当前目录内,UNIX将要求您使用路径名调用本命令.大多数命令都不在您所

Linux命令之awk命令使用介绍

  awk简介 awk是一个强大的文本分析工具,相对于grep的查找,sed的编辑,awk在其对数据分析并生成报告时,显得尤为强大.简单来说awk就是把文件逐行的读入,以空格为默认分隔符将每行切片,切开的部分再进行各种分析处理. awk有3个不同版本: awk.nawk和gawk,未作特别说明,一般指gawk,gawk 是 AWK 的 GNU 版本. awk其名称得自于它的创始人 Alfred Aho .Peter Weinberger 和 Brian Kernighan 姓氏的首个字母.实际上

Linux系统中的gdb程序调试工具的命令知识介绍

在Linux系统中有许多的命令程序来辅助系统的正常和方便运行,那么其中在系统中有着一个叫做gdb命令的程序,那么我们今天就来了解下关于gdb命令的知识吧! 一.常规调试 gdb是Linux下常用的程序调试工具,当然前提是用gcc/g++编译时加上-g参数,这样编译出的可执行程序会加上gdb调试信息. gdb命令不少,但常用的主要包括如下命令: (1)list [file:]functuon 命令缩写是l,查看源码,不加参数时,向下显示源码,加参数-l时,向上显示源码,默认显示10行. 也可以设置

JAVA和JAVAC 命令详细介绍_java

JAVA和JAVAC 命令 javac和java命令行中的-classpath选项 这是个很基础的问题,但是因为基本上都是用现有的IDE工具 来开发java程序,所以很少有人意识到这一点. javac -classpath,设定要搜索类的路径,可以是目录,jar文件,zip文件(里面都是class文件),会覆盖掉所有在CLASSPATH里面的设定. -sourcepath, 设定要搜索编译所需java 文件的路径,可以是目录,jar文件,zip文件(里面都是java文件). 所以一个完整的jav

HDFS命令行客户端使用,命令行客户端支持的命令参数,常用命令参数介绍

3.HDFS的shell(命令行客户端)操作 3.1HDFS命令行客户端使用 HDFS提供shell命令行客户端,使用方法如下: [toto@hadoop hadoop-2.8.0]$ hdfs dfs -ls /     (推荐使用这种方式,hdfs现在这种是最新的一种方式) Found 4 items drwxr-xr-x   - toto supergroup          0 2017-05-29 14:01 /findbugs-1.3.9 drwxr-xr-x   - toto s

基础:tar 命令使用介绍

基础:tar 命令使用介绍 Linux tar 命令是归档或分发文件时的强大武器.GNU tar 归档包可以包含多个文件和目录,还能保留其文件权限,它还支持多种压缩格式.Tar 表示 "Tape Archiver",这种格式是 POSIX 标准. Tar 文件格式 tar 压缩等级简介: 无压缩 没有压缩的文件用 .tar 结尾. Gzip 压缩 Gzip 格式是 tar 使用最广泛的压缩格式,它能快速压缩和提取文件.用 gzip 压缩的文件通常用 .tar.gz 或 .tgz 结尾.