引言

在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. 模拟美式橄榄球比赛数据(R)

    获得和清洗数据: 1.从网络上抓取数据 year<- url<-paste("http://sports.yahoo.com/nfl/stats/byteam?group=Off ...

  2. MongoDB学习笔记—windows下安装

    1.登录官网下载安装包 官网下载地址:https://www.mongodb.com/download-center?jmp=nav#community 根据你的系统下载 32 位或 64 位的 .m ...

  3. 201703 ABAP面试题002

    转自: ABAP 面试问题及答案(一):数据库更新及更改 SAP Standard (转) 问题一:锁对象(Lock Object)和 FM(Function Module)激活锁定对象时,产生的 F ...

  4. 系统日志服务rsyslog

    一.系统日志服务rsyslog:多线程,可以基于UDP.TCP.TLS协议进行远程通信,还可以将数据存储到MySQL.PGSQL.Oracle,强大的过滤器,可实现过滤日志信息中任何部分,可以自定义输 ...

  5. 3.6.使用STC89C52控制MC20解析GPS的经纬度数据上传到指定服务器

    需要准备的硬件 MC20开发板 1个 https://item.taobao.com/item.htm?id=562661881042 GSM/GPRS天线 1根 https://item.taoba ...

  6. 自制Javascript浮动广告

    <%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb ...

  7. C/C++ 数据类型的使用方法详解

    cppreference.com -> C/C++ 数据类型 C/C++ 数据类型 C语言包含5个基本数据类型: void, integer, float, double, 和 char. 类型 ...

  8. C语言预处理命令的使用

    cppreference.com -> 预处理命令 -> 详细说明 预处理命令 #,## # 和 ## 操作符是和#define宏使用的. 使用# 使在#后的首个参数返回为一个带引号的字符 ...

  9. Pacemaker详解

    一.前言 云计算与集群系统密不可分,作为分布式计算和集群计算的集大成者,云计算的基础设施必须通过集群进行管理控制,而作为拥有大量资源与节点的集群,必须具备一个强大的集群资源管理器(Cluster sy ...

  10. kafka connect简介以及部署

    https://blog.csdn.net/u011687037/article/details/57411790 1.什么是kafka connect? 根据官方介绍,Kafka Connect是一 ...