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

一:定义一个命令

二:定义命令的实现

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

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();
}
}


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

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

  1. WPF自学入门(十一)WPF MVVM模式Command命令 WPF自学入门(十)WPF MVVM简单介绍

    WPF自学入门(十一)WPF MVVM模式Command命令   在WPF自学入门(十)WPF MVVM简单介绍中的示例似乎运行起来没有什么问题,也可以进行更新.但是这并不是我们使用MVVM的正确方式 ...

  2. WPF中的命令(Command)

    这节来讲一下WPF中的命令(Command)的使用. [认识Command] 我们之前说过,WPF本身就为我们提供了一个基础的MVVM框架,本节要讲的命令就是其中一环,通过在ViewModel中声明命 ...

  3. WPF自己定义命令Command

    一.自己定义命令 自己定义命令必需要实现ICommand接口.例如以下代码所看到的: /// <summary> /// 自己定义的清除命令. 光脚丫思考 2014-7-31 06:51: ...

  4. WPF之事件绑定命令

    目录 事件绑定意义 无参数的事件绑定 带EventArgs参数的事件绑定 使用事件绑定 扩展:基于InvokeCommandAction源码的实现(推荐) 参考资料 事件绑定意义 一般事件的处理程序都 ...

  5. linux配置网卡IP地址命令详细介绍及一些常用网络配置命令

    linux配置网卡IP地址命令详细介绍及一些常用网络配置命令2010-- 个评论 收藏 我要投稿 Linux命令行下配置IP地址不像图形界面下那么方 便,完全需要我们手动配置,下面就给大家介绍几种配置 ...

  6. linux常用命令的介绍

    本文主要介绍Linux常用命令工具,比如用户创建,删除,文件管理,常见的网络命令等 如何创建账号: 1. 创建用户 useradd -m username -m 表示会在/home 路径下添加创建用户 ...

  7. Command Pattern -- 命令模式原理及实现(C++)

    主要参考<大话设计模式>和<设计模式:可复用面向对象软件的基础>两本书.本文介绍命令模式的实现. What it is:Encapsulate a request as an ...

  8. .bat批处理命令的介绍

    HUC = = D组 http://www.cnhonkerarmy.com/ 63707869 =====================================开始============ ...

  9. 浅谈Windows环境下DOS及MS-DOS以及常见一些命令的介绍

    浅谈Windows环境下DOS及MS-DOS以及常见一些命令的介绍 前记 自己是搞编程的,首先我是一个菜鸟,接触计算机这么久了,感觉很多计算机方面的技术和知识朦朦胧胧.模模糊糊,貌似有些贻笑大方了:所 ...

随机推荐

  1. centos7 搭建WEB服务器

    centos7 搭建WEB服务器 2017年09月17日 09:44:50 逝然1994 阅读数:18321 标签: centosapacheweb服务器 更多 个人分类: centos服务器简单配置 ...

  2. Method not found: 'System.Data.Entity.ModelConfiguration.Configuration.XXX

    使用EF flument API  修改映射数据库字段的自增长 modelBuilder.Entity<Invoice>().Property(p => p.Id).HasDatab ...

  3. openvSwitch 基本命令

    建立ovs接口连接两个namespace组成二层网络 环境搭建拓扑 br0 +--------------------------------------+ +--+ +--+ +---+ | tap ...

  4. 网页登入验证码的实现(java&html)

    前端界面实现(由于验证码是动态获取所以用jsp格式) <%@ page language="java" contentType="text/html; charse ...

  5. web开发常用网络优化

    优化方法: 1.合并资源文件,减少HTTP请求 2.压缩资源文件减少请求大小 3.利用缓存机制,尽可能使用缓存减少请求 如何做前端路由 html5 api中的history能够让我们控制url跳转之后 ...

  6. 浅谈getResource方法

    项目经常会读取一些配置文件, 因此getResource方法便能够起到重要作用 使用时主要是两种方法, 一个是字节码文件Class类, 另一个是ClassLoader类加载器 使用Class类时有两种 ...

  7. I/O类型

    同步和异步 synchronous  asyncronous 关注的是消息通知机制 同步:调用发出之后不会立即返回,但一旦返回,则返回即是最终结果. 异步:调用发出之后,被调用方立即返回消息,但返回的 ...

  8. 【多线程】:Synchronized和ReentrantLock的对比

    相同点: 两者都是可重入锁,同一个线程每进入一次,锁的计数器都自增1,等到锁的计数器下降为0时才能释放锁. 底层实现对比: Synchronized是依赖于JVM实现的,而ReentrantLock是 ...

  9. mysql之视图,存储过程,触发器,事务

    视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名称]即可获取结果集,可以将该结果集当做表来使用. 使用视图我们可以把查询过程中的临时 ...

  10. 在Ubuntu下编译安装nginx

    一.安装nginx 1.安装前提 a)epoll,linux内核版本为2.6或者以上 b)gcc编译器,g++编译器 c)pcre库,函数库,支持解析正则表达式 d)zlib库:压缩解压功能 e)op ...