【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 ...
随机推荐
- 使用nose_parameterized使unitTest实现参数化
nose-parameterized是一个针对Python单元测试框架实现参数化的扩展 import unittest # from nose_parameterized import paramet ...
- windows 安装 python _ flask
1:首先安装python虚拟环境;(略) 2: 添加一个虚拟环境: 在你的项目目录里直接 virtualenv venv 启动虚拟环境;\venv\Scripts 直接运行activate 3: 在虚 ...
- corethink功能模块探索开发(二)让这个模块可安装
要想让这个模块可安装,只需要在opcmf.php文件中写一些配置数据就行 随便写点 Equip/opencmf.php <?php // 模块信息配置 return array( // 模块信息 ...
- Linux文件IO
参考<unix高级环境编程> 本章开始讨论U N I X系统,先说明可用的文件I / O函数——打开文件.读文件.写文件等等.大多数U N I X文件I / O只需用到5个函数:o p e ...
- php备份mysql数据库
<?php /*程序功能:mysql数据库备份功能*/ ini_set('max_execution_time','0'); ini_set('memory_limit','1024M');// ...
- 《高级程序设计》8 BOM
window对象 location对象 navigator对象 screen对象 history对象 一.window对象 BOM的核心对象是window,它表示浏览器的一个实例.在浏览器中,wind ...
- 主攻ASP.NET MVC4.0之重生:ASP.NET MVC Web API
UserController代码: using GignSoft.Models; using System; using System.Collections.Generic; using Syste ...
- 逐行读取txt文件并存入到数组中
get_file_contents_on_line.php $file = fopen("log.txt", "r"); $user=array(); $i=0 ...
- class_alias--为一个类创建别名
class_alias--为一个类创建别名 bool class_alias ( string $original , string $alias [, bool $autoload = TRUE ] ...
- 常见Web安全漏洞
1.web安全常见攻击手段 xss sql注入 防盗链 csrf 上传漏洞 2. 信息加密与漏洞扫描 对称加密 非对称加密 3. 互联网API接口安全设计 4. 网站安全漏洞扫描与 ...