引言

在MVVM模式开发下,命令Command是编程中不可或缺的一部分.下面,我分3种场景简单介绍一下命令的用法.

ViewModel中的命令

在ViewModel定义命令是最常用的用法,开发中几乎90%以上的命令都在用在ViewModel上.怎么用?先从实现ICommand说起,下面定义一个命令

    public class MyCommand :ICommand
{
public bool CanExecute(object parameter)
{
return true;
}
public event EventHandler CanExecuteChanged; public void Execute(object parameter)
{
MessageBox.Show("命令已经执行!");
}
}

然后在ViewModel中定义一个命令,赋值MyCommand,接着在View绑定命令,如下

    public class MainWindowViewModel
{
public MainWindowViewModel()
{
myCommand = new MyCommand();
}
public ICommand myCommand {get ; set ; } }
<Window x:Class="WpfCommand.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfCommand"
Title="MainWindow" Height="" Width="">
<Grid>
<Button Command="{Binding myCommand}" Name="btn" Height="" Width="" Margin="104,75,0,0" VerticalAlignment="Top" HorizontalAlignment="Left">执行命令</Button>
</Grid>
</Window>

上面看起来不复杂,但是实际开发绝对不这么干的,如果每个命令都要自定义类,还能好好玩耍么.实际开发,我们可以借助第三方类轻松完成我们的命令实现,如Prism框架的DelegateCommand,MVVMLight的RelayCommand,下面演示一下DelegateCommand,只需在ViewModel中实例化一个命令既可.

 public class MainWindowViewModel
{
public MainWindowViewModel()
{
myCommand = new DelegateCommand(() => { MessageBox.Show("命令已经执行!"); }, () => true);
}
public ICommand myCommand {get ; set ; }
}

 自定义控件中的命令绑定

在自定义控件中绑定命令不常见,但是某些场景下还是有用的.例如DataGrid的新增行,删除行,绑定自定义命令,让外部调用还是很有用的.下面,用继承TextBox做个演示吧.

利用CommandManager绑定命令,命令的作用是将字体变成红色,无文本时则命令不可用.MyTextBox定义如下

public  class MyTextBox:TextBox
{ static MyTextBox()
{
CommandManager.RegisterClassCommandBinding(typeof(MyTextBox),
new CommandBinding(MyCommands.MyRoutedCommand,
Command_Executed, Command_CanExecute));
} private static void Command_CanExecute(object sender, CanExecuteRoutedEventArgs e)
{
MyTextBox myTextBox = (MyTextBox)sender;
e.CanExecute = !string.IsNullOrWhiteSpace(myTextBox.Text);
}
private static void Command_Executed(object sender, ExecutedRoutedEventArgs e)
{
MyTextBox myTextBox = (MyTextBox)sender;
myTextBox.Foreground = new SolidColorBrush(Colors.Red);
}
}
 public class MyCommands
{
private static RoutedUICommand myRoutedCommand;
static MyCommands()
{
myRoutedCommand = new RoutedUICommand(
"MyRoutedCommand", "MyRoutedCommand", typeof(MyCommands));
}
public static RoutedUICommand MyRoutedCommand
{
get { return myRoutedCommand; }
}
}

如何使用,很简单,设置一下Button的Command和CommandTarget即可,如下

<Window x:Class="WpfCommand.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfCommand"
Title="MainWindow" Height="" Width="">
<Grid>
<local:MyTextBox x:Name="mytextbox"></local:MyTextBox>
<Button Command="local:MyCommands.MyRoutedCommand" CommandTarget="{Binding ElementName=mytextbox}" Name="btn" Height="" Width="" Margin="104,75,0,0" VerticalAlignment="Top" HorizontalAlignment="Left">执行命令</Button> </Grid> </Window>

自定义控件中的命令属性

在WPF的控件库,我们会发现很多控件都带有Command,例如Button.控件中有Command属性才能让我们如期望地执行命令.如果我们的自定义控件想定义这个Command,就要实现ICommandSource了.下面从定义一个简单按钮来演示一下.

public class MyButton : ContentControl,ICommandSource
{
public static readonly DependencyProperty CommandProperty =
DependencyProperty.Register(
"Command",
typeof(ICommand),
typeof(MyButton),
new PropertyMetadata((ICommand)null,
new PropertyChangedCallback(CommandChanged))); public ICommand Command
{
get
{
return (ICommand)GetValue(CommandProperty);
}
set
{
SetValue(CommandProperty, value);
}
} public static readonly DependencyProperty CommandTargetProperty =
DependencyProperty.Register(
"CommandTarget",
typeof(IInputElement),
typeof(MyButton),
new PropertyMetadata((IInputElement)null)); public IInputElement CommandTarget
{
get
{
return (IInputElement)GetValue(CommandTargetProperty);
}
set
{
SetValue(CommandTargetProperty, value);
}
} public static readonly DependencyProperty CommandParameterProperty =
DependencyProperty.Register(
"CommandParameter",
typeof(object),
typeof(MyButton),
new PropertyMetadata((object)null)); public object CommandParameter
{
get
{
return (object)GetValue(CommandParameterProperty);
}
set
{
SetValue(CommandParameterProperty, value);
}
} private static void CommandChanged(DependencyObject d,
DependencyPropertyChangedEventArgs e)
{ }
//在鼠标的按下事件中,调用命令的执行
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
base.OnMouseLeftButtonDown(e); if (!Command.CanExecute(CommandParameter))
return;
Command.Execute(CommandParameter);
}
}

上面只是简单地定义了命令,实际上Button的Command定义要比上面复杂些,有兴趣的童鞋可以去看看Button的源码,推荐一款反编译神器dotPeek.下面是Xaml的定义.

<Window x:Class="WpfCommand.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfCommand"
Title="MainWindow" Height="" Width="">
<Grid>
<local:MyTextBox x:Name="mytextbox"></local:MyTextBox>
<local:MyButton Height="" Width="" Command="local:MyCommands.MyRoutedCommand" CommandTarget="{Binding ElementName=mytextbox}" >
<Ellipse Fill="Blue">
</Ellipse>
</local:MyButton>
</Grid>
</Window>

 小结

本着从实际出发的原则,命令的介绍和其他内容被我省略了.最后,如果你有更好的想法,请不吝留言指教.

【WPF】命令系统的更多相关文章

  1. WPF学习之深入浅出话命令

    WPF为我们准备了完善的命令系统,你可能会问:"有了路由事件为什么还需要命令系统呢?".事件的作用是发布.传播一些消息,消息传达到了接收者,事件的指令也就算完成了,至于如何响应事件 ...

  2. WPF 核心体系结构

    WPF 体系结构 主题提供 Windows Presentation Foundation (WPF) 类层次结构,涵盖了 WPF 的大部分主要子系统,并描述它们是如何交互的. System.Obje ...

  3. WPF Demo19 命令、UC

    命令系统的基本元素和关系WPF命令系统的组成要素:A.命令(command):WPF命令实际上就是实习了ICommand接口的类.平时使用最多的就是RoutedCommand类.B.命令源(comma ...

  4. 《深入浅出WPF》读书笔记

    依赖属性: 节省实例对内存的开销: 属性值可以通过Binding依赖到其他对象上. WPF中,依赖对象的概念被DependencyObject类实现,依赖属性被DependencyProperty类实 ...

  5. WPF 跟踪命令和撤销命令(复原)

    WPF 命令模型缺少一个特性是复原命令.尽管提供了一个 ApplicationCommands.Undo 命令,但是该命令通常被用于编辑控件(如 TextBox 控件),以维护它们自己的 Undo 历 ...

  6. WPF命令绑定 自定义命令

    WPF的命令系统是wpf中新增加的内容,在以往的winfom中并没有.为什么要增加命令这一块内容.在winform里面的没有命令只使用事件的话也可以实现程序员希望实现的功能.这个问题在很多文章中都提到 ...

  7. 命令——WPF学习之深入浅出

    WPF学习之深入浅出话命令   WPF为我们准备了完善的命令系统,你可能会问:“有了路由事件为什么还需要命令系统呢?”.事件的作用是发布.传播一些消息,消息传达到了接收者,事件的指令也就算完成了,至于 ...

  8. 【WPF学习】第三十三章 高级命令

    前面两章介绍了命令的基本内容,可考虑一些更复杂的实现了.接下来介绍如何使用自己的命令,根据目标以不同方式处理相同的命令以及使用命令参数,还将讨论如何支持基本的撤销特性. 一.自定义命令 在5个命令类( ...

  9. WPF 体系结构

    转载地址:http://blog.csdn.net/changtianshuiyue/article/details/38963477 本主题提供 Windows Presentation Found ...

  10. C#用户自定义控件(含源代码)-透明文本框

    using System; using System.Collections; using System.ComponentModel; using System.Drawing; using Sys ...

随机推荐

  1. 010-spring事务管理

    一.Spring的事务传播行为 事务是从哪里传播到哪里? 是从方法A传播至方法B. Spring事务类型详解: PROPAGATION_REQUIRED--如果当前没有事务,就新建一个事务.如果有,就 ...

  2. Oracle学习笔记—oracle体系架构及状态(nomount、mount和open)简介

    oracle体系架构简介 先来简要了解一下Oracle数据库体系架构以便于后面深入理解,Oracle Server主要由实例(instance)和数据库(database)组成.实例(instance ...

  3. rar 7z文件打包

    把D:\file目录下的所有东西打包为file.rar放到D:\目录下, Rar.exe是放在c盘根目录下 >>C:\Rar.exe a -k -r -s -m1 D:\file.rar ...

  4. oc字符串+数组+字典操作题目

    1. 判断中间目录是否存在 (10分) 比如 传入字符串 @"/home/qianfeng/oc.txt" 和 @"qianfeng" 返回:YES 传入字符串 ...

  5. $Java-json系列(一):用GSON解析Json格式数据

    GSON是谷歌提供的开源库,用来解析Json格式的数据,非常好用.如果要使用GSON的话,则要先下载gson-2.2.4.jar这个文件,如果是在Android项目中使用,则在Android项目的li ...

  6. centos中安装php7

    centos7下安装php7 php7 centos7 安装PHP7 首先安装一些必须的依赖,这里就不阐述了,后面文章再细说 yum install -y \ gcc-c++ autoconf \ l ...

  7. flask实现模仿知乎

    上个月花了一个月的时间学习flask框架实现了一个简陋的知乎,有提问,回答,写文章,个人信息页,个人信息修改等功能,因刚接触学习flask,后端代码实现很多冗余,依旧需要修改. github: htt ...

  8. 主攻ASP.NET.4.5 MVC4.0之重生:图书推荐

    前段时间看完ASP.Net4.0 框架揭秘 ,目前现在此书在家睡大觉,看得云里雾里,实战有些东西用不上,感觉好可惜. 大概看了一下这本书,这本书很多功能,可以在实际项目中能用上的方法和技巧.小小推荐, ...

  9. Linux设置默认启动命令行,而不是图形界面

    无论是作为上线的服务器还是开发中的虚拟机来说,都是没有必要启动图形界面的,而图形界面占用的内存还是很大的.枫竹梦本文就介绍如何设置来默认启动命令行. 其实就是设置系统的启动级别. CentOS的设置 ...

  10. mini2440移植uboot 2014.04(五)

    代码上传到github上:https://github.com/qiaoyuguo/u-boot-2014.04-mini2440 前几篇博文: <mini2440移植uboot 2014.04 ...