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();
}
}
如果感觉不错的话,请帮忙推荐,谢谢……
WPF命令(Command)介绍、命令和数据绑定集成应用的更多相关文章
- WPF自学入门(十一)WPF MVVM模式Command命令 WPF自学入门(十)WPF MVVM简单介绍
WPF自学入门(十一)WPF MVVM模式Command命令 在WPF自学入门(十)WPF MVVM简单介绍中的示例似乎运行起来没有什么问题,也可以进行更新.但是这并不是我们使用MVVM的正确方式 ...
- WPF中的命令(Command)
这节来讲一下WPF中的命令(Command)的使用. [认识Command] 我们之前说过,WPF本身就为我们提供了一个基础的MVVM框架,本节要讲的命令就是其中一环,通过在ViewModel中声明命 ...
- WPF自己定义命令Command
一.自己定义命令 自己定义命令必需要实现ICommand接口.例如以下代码所看到的: /// <summary> /// 自己定义的清除命令. 光脚丫思考 2014-7-31 06:51: ...
- WPF之事件绑定命令
目录 事件绑定意义 无参数的事件绑定 带EventArgs参数的事件绑定 使用事件绑定 扩展:基于InvokeCommandAction源码的实现(推荐) 参考资料 事件绑定意义 一般事件的处理程序都 ...
- linux配置网卡IP地址命令详细介绍及一些常用网络配置命令
linux配置网卡IP地址命令详细介绍及一些常用网络配置命令2010-- 个评论 收藏 我要投稿 Linux命令行下配置IP地址不像图形界面下那么方 便,完全需要我们手动配置,下面就给大家介绍几种配置 ...
- linux常用命令的介绍
本文主要介绍Linux常用命令工具,比如用户创建,删除,文件管理,常见的网络命令等 如何创建账号: 1. 创建用户 useradd -m username -m 表示会在/home 路径下添加创建用户 ...
- Command Pattern -- 命令模式原理及实现(C++)
主要参考<大话设计模式>和<设计模式:可复用面向对象软件的基础>两本书.本文介绍命令模式的实现. What it is:Encapsulate a request as an ...
- .bat批处理命令的介绍
HUC = = D组 http://www.cnhonkerarmy.com/ 63707869 =====================================开始============ ...
- 浅谈Windows环境下DOS及MS-DOS以及常见一些命令的介绍
浅谈Windows环境下DOS及MS-DOS以及常见一些命令的介绍 前记 自己是搞编程的,首先我是一个菜鸟,接触计算机这么久了,感觉很多计算机方面的技术和知识朦朦胧胧.模模糊糊,貌似有些贻笑大方了:所 ...
随机推荐
- INDEX--从数据存放的角度看索引
测试表结构: CREATE TABLE TB1 ( ID ,), C1 INT, C2 INT ) 1. 聚集索引(Clustered index) 聚集索引可以理解为一个包含表中除索引键外多有剩余列 ...
- ASP.NET WebAPI (反)序列化用[SerializableAttribute]修饰的类的一个坑
发现问题 在 ASP.NET WebAPI 项目中,有这样的 ViewModel 类: [Serializable] class Product { public int Id { get; set; ...
- MVC中通过ajax判断输入的内容是否重复(新手笔记,请各位多多指教)
控制器代码: public string ValidateCarID(string carid)//这里接收ajax传递过来的值 { string result; Car car = db.Car.F ...
- Facebook内部报告:争取青少年用户的鸡贼小技巧
翻译:吴祺深 欢迎访问网易云社区,了解更多网易技术产品运营经验. 去年十月,Facebook收购了TBH,最后却关闭了这款APP,不过一则内部报告透露了,通过这款流行的投票APP,这家公司学会了如何去 ...
- Python 关于 encode与decode 中文乱码问题
字符串在Python内部的表示是unicode编码,因此,在做编码转换时,通常需要以unicode作为中间编码,即先将其他编码的字符串解码(decode)成unicode,再从unicode编码(en ...
- Bash/Shell-脚本整理(长期更新)
轮询检测Apache状态并启用钉钉报警 #!/bin/bash shell_user="root" shell_domain="apache" shell_li ...
- C语言Socket-单工通信(客户端向服务器发送数据)
服务端(server) #include <stdio.h> #include <winsock2.h> #pragma comment(lib,"ws2_32.li ...
- Tree with Small Distances(cf1029E)(树形动规)
You are given an undirected tree consisting of \(n\) vertices. An undirected tree is a connected und ...
- ArrayList的源码分析
在项目中经常会用到list集合来存储数据,而其中ArrayList是用的最多的的一个集合,这篇博文主要简单介绍ArrayList的源码分析,基于JDK1.7: 这里主要介绍 集合 的属性,构造器,和方 ...
- linux定时重启tomcat服务的脚本学习
要求:在linux中定时重启一个tomcat服务 一:shell脚本即Shell Script [1],Shell脚本与Windows/Dos下的批处理相似,也就是用各类命令预先放入到一个文件中,方便 ...