在使用MVVM模式时, 按照模式的规则是尽量不直接使用事件. 所以对于以前一直使用事件模式的同行来说确实有点头疼. 还好微软给我们提供了几种间接使用事件(命令)的方法, 下面我就来看看这几种方法:

ICommand

ICommand定义了一个接口, 使用它可以轻松的将实现ICommand的接口的命令绑定到包含命令(Command)的控件上(例如Button.Command), 在.net framework库中实现的这个接口的类不是很多, 我所知道的两个: RoutedCommand 和 RoutedUICommand, 而且这两个使用起来比较麻烦, 在这里我就不谈了, 有兴趣的同行可以研究一下. 那么, 除了上述的两个类以外还有自定义类实现ICommand和Prism的DelegateCommand. 我们先看一下自定义的;

1. 自定义命令

MyCommand是实现ICommand接口的一个类. 在Execute方法中我们调用传入的Action(Action包含所要实现的功能的方法), IsEnabledExecute是自定义的一个bool类型, 通过设置该值可以启用(禁用)ICommand所绑定到的控件的启用禁用状态.

 

定义好MyCommand后我们就可以使用了, 代码如下:

<!--XAML-->

首先定义了MvvmEventViewModel, 在MvvmEventViewModel中实例化了MyCommand, 将Button所在的界面或者用户控件的属性DataContext绑定上MvvmEventViewModel的实例, 最后直接在Button的Command属性上绑定MyCommandInstance;

2.prism命令

prism是微软的一个开源框架, 其为WPF(SL)而生, 自然也少不了MVVM模式的一些辅助类, 其中命令就是典型的辅助类. 在上面我们是自定义命令, 其实在prism框架中已经提供了命令类, 那就是DelegateCommand, 该类还为泛型提供了支持; 不仅如此prism还提供了多个命令的绑定CompositeCommand, 为一个Button命令可以执行多个方法问题提供了廉价的解决方案.

2.1. DelegateCommand 命令

DelegateCommand 命令与我们上面自定义的命令一样, 都是可以绑定到Button的Command属性上, 使用该类少了几行代码, 多了一份省心和安全. 如果让我选择我会选择DelegateCommand类而摒弃自定义类, 因为它可以实现我们需要的功能, 所以就没必要再重造轮子.

<!--XAML-->

2.2.CompositeCommand 命令

CompositeCommand 命令可以理解为一个命令组. 将ICommand注册到CompositeCommand中, 然后绑定在Command上, 就可以让Command触发注册到CompositeCommand的所有命令.

2.2.1.定义一个CompositeCommand命令

2.2.2.使用CompositeCommand命令

Comm.CompositeCommand.RegisterCommand(MyCommandInstance);

Comm.CompositeCommand.RegisterCommand(MyDelegateCommandInstance);

<!--XAML-->

xmlns:comm="clr-namespace:Blogs.WPF"

<Button Width="180"

                Height="23"

                Margin="0,0,7,0"

                HorizontalAlignment="Left"

                Command="{x:Static comm:Comm.CompositeCommand}"

                CommandParameter="DelegateCommand"

                Content="CompositeCommand Button" />

将我们刚才定义的两个命令MyCommandInstance和MyDelegateCommandInstance注册到 Comm.CompositeCommand中, 然后在一个Button上绑定 comm:Comm.CompositeCommand 此时我们单击CompositeCommand Button时发现触发了两个命令. 同样的我们也可以使用UnregisterCommand卸载命令.

2.3.将其他事件绑定到ICommand上

在上述的例子中我们只是在Button的Command属性上绑定ICommand, 那么对于一些特殊事件(如Loaded, MouseDown, MouseUp)我们该怎么处理呢? 网上也有一些传统的方法, 将控件直接传送到VM中, 使用+=创建特殊的事件. 其实还有更好的办法, 那就是System.Windows.Interactivity.dll 组件.

在你的项目中引入System.Windows.Interactivity.dll, 然后在页面中添加如下代码: xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"

OK, 现在就让我们就来使用这两个组件, 代码简单, 请看:

public DelegateCommand LostFocusCommand { get; private set; }

LostFocusCommand = new DelegateCommand(LostFocusMethod);

private void LostFocusMethod()

{

MessageBox.Show("捕获到了.嘿牟嘿牟.");

}
<TextBlock Background="OrangeRed" Text="左键按下时我能捕获到">

<i:Interaction.Triggers>

<!-- 当单击鼠标左键按下时 -->

<i:EventTrigger EventName="MouseLeftButtonDown">

<i:InvokeCommandAction Command="{Binding LostFocusCommand}" />

</i:EventTrigger>

</i:Interaction.Triggers>

</TextBlock>

注: 名字起的有点不对应. 不想改了, 大家知道就可以.

以上是使用System.Windows.Interactivity.dll组件可以将事件直接绑定到命令上, 但是我觉得这样麻烦, 如果可以直接使用事件岂不是更爽. 呵呵. 能提出问题就能解答问题. 我们再看另一个组件 Microsoft.Expression.Interactions.dll .

同样的, 项目中引用 Microsoft.Expression.Interactions.dll

添加命名空间

xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"

<UserControl>

<i:Interaction.Triggers>

<i:EventTrigger EventName="Loaded">

<ei:CallMethodAction MethodName="View_Loaded" TargetObject="{Binding}" />

</i:EventTrigger>

</i:Interaction.Triggers>

</UserControl>

注意: 在多层项目中. 只要你使用System.Windows.Interactivity.dll, Microsoft.Expression.Interactions.dll 这两个组件, 就必须在启动层中引用这两个DLL, 否则报错.

源码地址: 点击下载

作者:Crazy大象
出处:http://www.cnblogs.com/ynbt/
关于作者:专注于.Net、WCF和移动互联网开发。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,如有问题,可以通过m1327379@163.com联系我,非常感谢。 。

MVVM - 事件转命令2的更多相关文章

  1. MVVM 事件转命令1

    EventToCommand 在WPF中,并不是所有控件都有Command,例如TextBox,那么当文本改变,我们需要处理一些逻辑,这些逻辑在ViewModel 中,没有Command如何绑定呢?这 ...

  2. WPF Prism框架下基于MVVM模式的命令、绑定、事件

    Prism框架下的自定义路由事件和命令绑定 BaseCode XAML代码: <Button x:Class="IM.UI.CommandEx.PrismCommandEx" ...

  3. WPF使用MVVM(三)-事件转命令

    WPF使用MVVM(三)-事件转命令 上一节介绍了WPF中的命令,可是仅仅介绍的是WPF框架给我们提供的点击命令,也就是用Command属性来绑定一个命令,用来响应按钮的点击行为!显然这是不够的,界面 ...

  4. WPF自学入门(十一)WPF MVVM模式Command命令 WPF自学入门(十)WPF MVVM简单介绍

    WPF自学入门(十一)WPF MVVM模式Command命令   在WPF自学入门(十)WPF MVVM简单介绍中的示例似乎运行起来没有什么问题,也可以进行更新.但是这并不是我们使用MVVM的正确方式 ...

  5. WPF自学入门(十一)WPF MVVM模式Command命令

    在WPF自学入门(十)WPF MVVM简单介绍中的示例似乎运行起来没有什么问题,也可以进行更新.但是这并不是我们使用MVVM的正确方式.正如上一篇文章中在开始说的,MVVM的目的是为了最大限度地降低了 ...

  6. WPF之事件绑定命令

    目录 事件绑定意义 无参数的事件绑定 带EventArgs参数的事件绑定 使用事件绑定 扩展:基于InvokeCommandAction源码的实现(推荐) 参考资料 事件绑定意义 一般事件的处理程序都 ...

  7. 在WPF中的ItemsControl中使用事件和命令(Using events and Commands within ItemsControl in WPF)

    Say I have a standard WPF ItemsControl bound to an ObservableCollection of "Dog" objects l ...

  8. MVVM模式的命令绑定

    命令绑定要达到的效果 命令绑定要关注的核心就是两个方面的问题,命令能否执行和命令怎么执行.也就是说当View中的一个Button绑定了ViewModel中一个命令后,什么时候这个Button是可用的, ...

  9. WPF 事件触发命令

    方法一使用mvvmlight: xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Int ...

随机推荐

  1. JS设置localStorage有效期

    localStorage是一个没有时间限制的数据存储,如果没有手动删除它,它将永久保存. 但是有些时候我们又需要它在一段时间后自动删除,这里我们可以对它进行扩展. var date = new Dat ...

  2. Foxman, 基于微核架构的 Mock 解决方案

    本文来自 网易云社区 . Foxman ⇗ 是一个使用 Node.js 开发的命令行工具,定位是一个可扩展的 Mock Server,帮助前端开发者轻松.独立.高效地进行前端开发和完成后续的联调工作. ...

  3. Javascript获取select的选中值和选中文本(转载)

    var obj = document.getElementById(”select_id”); //selectid var index = obj.selectedIndex; // 选中索引 va ...

  4. 趣图:当我捕获Bug的时候

      趣图:当我以为已捕获了所有可能的异常...的时候 趣图:程序员调 Bug 的感觉,就是这样的

  5. 8、insert、delete、update语句总结

    insert常用语句 > insert into tb1 (name,age) values('tom',33); > insert into tb1 (name,age) values( ...

  6. POJ - 2421 Constructing Roads (最小生成树)

    There are N villages, which are numbered from 1 to N, and you should build some roads such that ever ...

  7. scrapy下载中间件,UA池和代理池

    一.下载中间件 框架图: 下载中间件(Downloader Middlewares) 位于scrapy引擎和下载器之间的一层组件. - 作用: (1)引擎将请求传递给下载器过程中, 下载中间件可以对请 ...

  8. 用最短的payload绕过WAF(入门)

    本文作者:jishuzhain <font color=green>想绕过一个WAF,我们可以用最短的payload来做,这里只是基础示例,望各位大佬勿喷,小弟在此谢过.</font ...

  9. composer手动安装到windows

    1.配置系统变量 Path 计算机->高级系统设置->环境变量->找到系统变量Path  双击 加入  ;php根目录地址:php中ext地址    如 :“;D:\phpStudy ...

  10. 使用 final 关键字修饰一个变量时,是引用不能变,还是引用的对象不能变?

    使用 final 关键字修饰一个变量时,是指引用变量不能变,引用变量所指向的对象中的内容还是可以改变的.例如,对于如下语句:final StringBuffer a=new StringBuffer( ...