【WPF】命令系统
引言
在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】命令系统的更多相关文章
- WPF学习之深入浅出话命令
WPF为我们准备了完善的命令系统,你可能会问:"有了路由事件为什么还需要命令系统呢?".事件的作用是发布.传播一些消息,消息传达到了接收者,事件的指令也就算完成了,至于如何响应事件 ...
- WPF 核心体系结构
WPF 体系结构 主题提供 Windows Presentation Foundation (WPF) 类层次结构,涵盖了 WPF 的大部分主要子系统,并描述它们是如何交互的. System.Obje ...
- WPF Demo19 命令、UC
命令系统的基本元素和关系WPF命令系统的组成要素:A.命令(command):WPF命令实际上就是实习了ICommand接口的类.平时使用最多的就是RoutedCommand类.B.命令源(comma ...
- 《深入浅出WPF》读书笔记
依赖属性: 节省实例对内存的开销: 属性值可以通过Binding依赖到其他对象上. WPF中,依赖对象的概念被DependencyObject类实现,依赖属性被DependencyProperty类实 ...
- WPF 跟踪命令和撤销命令(复原)
WPF 命令模型缺少一个特性是复原命令.尽管提供了一个 ApplicationCommands.Undo 命令,但是该命令通常被用于编辑控件(如 TextBox 控件),以维护它们自己的 Undo 历 ...
- WPF命令绑定 自定义命令
WPF的命令系统是wpf中新增加的内容,在以往的winfom中并没有.为什么要增加命令这一块内容.在winform里面的没有命令只使用事件的话也可以实现程序员希望实现的功能.这个问题在很多文章中都提到 ...
- 命令——WPF学习之深入浅出
WPF学习之深入浅出话命令 WPF为我们准备了完善的命令系统,你可能会问:“有了路由事件为什么还需要命令系统呢?”.事件的作用是发布.传播一些消息,消息传达到了接收者,事件的指令也就算完成了,至于 ...
- 【WPF学习】第三十三章 高级命令
前面两章介绍了命令的基本内容,可考虑一些更复杂的实现了.接下来介绍如何使用自己的命令,根据目标以不同方式处理相同的命令以及使用命令参数,还将讨论如何支持基本的撤销特性. 一.自定义命令 在5个命令类( ...
- WPF 体系结构
转载地址:http://blog.csdn.net/changtianshuiyue/article/details/38963477 本主题提供 Windows Presentation Found ...
- C#用户自定义控件(含源代码)-透明文本框
using System; using System.Collections; using System.ComponentModel; using System.Drawing; using Sys ...
随机推荐
- Linux下简单的多线程编程--线程池的实现
/* 写在前面的话: 今天刚“开原”,选择了一篇关于线程池的文件与大家分享,希望能对您学习有所帮助,也希望能与大家共同学习! 选择在这个特殊的时候注册并发文章也是有一些我个人特殊的意义的,看我的id( ...
- 20170520 BADI增强学习
一.要求:Tcode:FF_5 导入数据运行时,产生财务凭证之前修改某些字段值.Exmp:FEBRE-VWEZWBKPF-XBLNRFEBEP-CHECTBSEG-ZUONR there is a b ...
- VIMTUTOR 1.7中文版
文章来源:http://waterxfire.blog.hexun.com/4106986_d.html =============================================== ...
- Android Integer.parseInt java.lang.NumberFormatException: Invalid int解决方法
解决方法: http获取的字符串minutes去空字符串处理minutes.replaceAll("\\D+","").replaceAll("\r& ...
- iOS 11 Xcode9开发 新特性学习 (新方法篇)
1 . 引入github (1) 在Xcode 9 中,引入了 gitHub,新源代码管理导航器 可以展示branch分支和 tag标签. (2)点进去,就可以看指定一次commit了哪些东西 2 ...
- Linux文件系统管理 文件系统
概述 文件系统:文件系统这个名词大家都很陌生,不过如果说成分区,大家就比较容易理解了.原先每个分区只能格式化为一个文件系统,所以我们可以认为文件系统就是指分区.不过随着技术的进步,现在一个文件系统可以 ...
- 使用bedtools的一个问题
问题:有两个平行测序样本,分别得到1.vcf和2.vcf两个文件,想知道这两个文件有多少个重合点. [wangjq@mgmt CHG029194]$ cat t1 chr1 10 10 chr1 11 ...
- iOS面试必备-iOS基础知识
近期为准备找工作面试,在网络上搜集了这些题,以备面试之用. 插一条广告:本人求职,2016级应届毕业生,有开发经验.可独立开发,低薪求职.QQ:895193543 1.简述OC中内存管理机制. 答:内 ...
- INSPIRED启示录 读书笔记 - 第5章 产品管理与软件开发
保持融洽的合作关系 形成合作关系的关键是双方承认彼此平等——任何一方不从属于另一方,产品经理负责定义正确的产品,开发团队负责正确地开发产品,双方相互依赖 产品经理要求开发团队完成任务,必须先取得他们的 ...
- vRA7 Business error “Untrusted certificate chain”
报错截图: 服务无法注册 第一步:登录vRB 5480页面,取消到vRA的注册 第二部:SSH登录到VRB中,查看bio-ssl.keystore.password. cat /shared/cata ...