【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 ...
随机推荐
- 阿里云下 centos7下启动程序总是被killed ,看内存占用情况以检查哪些服务存在问题并调整参数作调优
很久不搭理自己的网站了,几天突然发现启动程序总是被killed, 于是查看了系统日志 vi /var/log/messages 发现出现 kernel: Out of memory: Kill pro ...
- 解决You are using pip version 9.0.1, however version 9.0.3 is available. You should consider upgra
直接运行命令:python -m pip install --upgrade pip
- IIS 6.0上部署.NET 4.0网站
最近需要把VS2010开发的网站部署到Windows Server 2003的服务器上去, Windows Server 2003操作系统自带的为IIS 6.0,IIS 6.0一般只支持.NET 2. ...
- "export" in SHELL
在shell中,若某一变量需要在随后的子程序中运行,则需要以 export 来使变量变成环境变量: export var export的用法总结: 1:一个shell中用export定义的变量,只对当 ...
- Hibernate一对多、多对一关联
一对多.多对一关联:在多方加外键 示例:Group(一方)和User(多方),一个Group可以有多个User,每个User只能属于一个Group 多对一单向关联 在User(多方)中建Group ...
- Linux常用指令——周琛
ps ax | grep java 查看进程命令里带“java”字样的进程信息,第一列是进程号 kill -9 1234 强制杀死1234号进程 cd /xxx/xxx 进入/xxx/xxx目录 cd ...
- Hearbeat + Nginx 安装配置
Hearbeat + Nginx 安装配置 实验环境 两台主机:Linux Centos 6.5 32位 主 服务端:Hearbeat + Nginx eth0:192.168.1.160(公网) e ...
- [RK3288][Android6.0] USB OTG模式及切换【转】
本文转载自:https://blog.csdn.net/kris_fei/article/details/78620960 Platform: RK3288 OS: Android 6.0 Kerne ...
- 通过公钥解密密文思路(256bits RSA)
256bit RSA公钥安全系数极低,只需要几分钟即可破解密文,本文综合其他文章记录了一次解密256bits RSA加密的密文的过程,仅作为备忘. 1.分解公钥,分解出n与e: 1.1使用openss ...
- Centos7 关闭Ipv6