原文:管窥MVVMLight Command参数绑定和事件传递

前言

由于在实际项目中,业务功能的增加导致软件开发规模在逐渐变大,所以我准备找个Silverlight框架来组织当前项目中的文件,以期能够让后续的业务功能增添和维护更加容易一些。无意中,我在这篇文章中看到了当前Silverlight下所有的框架的评测:Discover and compare existing MVVM frameworks !,当我看到MvvmLight toolkit在各方面都比较完备的时候,于是决定选择这个框架:

在Codeplex网站上,下载了MVVM Light Toolkit V4 RTM这个版本,因为我用的是vs2010,所以我下载了支持当前机器IDE的版本。

新建项目,选择MvvmLight(SL4),之后我们就可以看到项目结构了:

其中:

Design文件夹中的文件主要提供设计时运行支持

Model文件夹则放置了富实体模型

Skins文件夹则放置了样式文件定义

ViewModel文件夹则放置了ViewModel对象,其实MainViewModel和MainPage是一对一的(ViewMoel-View)关系.二者的映射通过ViewModelLocator进行。

MainPage.xaml就是我们的视图页面

下面我们就以例子来演示MvvmLight Toolkit中是如何实现MVVM模式,如何绑定命令,如何进行事件消息传递的。

首先,在这个框架中,MVVM模式的入口点为ViewModelLocator类,在这个类中,可以定义多个ViewModel属性,并且每个属性都可以通过ServiceLocator.Current.GetInstance方法进行映射,以便于暴露给前台绑定。同时,在新增一个ViewModel类的时候,一定要在其提供的SimpleIoc对象容器中进行注册,以便于能够通过IOC的方式获取其实例。

做完映射后,就是我们的ViewModel对象了。它需要继承自ViewModelBase类,这个类封装了ICommand,INotifypropertyChanged等接口,使用起来很方便。比如可以用RaisePropertyChanged直接来抛出变更通知。

之后就是View了,在View中,我们需要先对DataContext进行绑定:

DataContext="{Binding Main, Source={StaticResource Locator}}"

然后就可以随心所欲的操作了。

然后,我们来讲解下绑定命令。

由于命令绑定是应用程序中必不可少的环节,所以这里我以 绑定无参事件,绑定一个参数事件,绑定多个参数事件来说明。

绑定无参事件:

  #region Command without parametersprivate RelayCommand showText;public RelayCommand ShowText{get{if (showText == null)showText = new RelayCommand(ShowTextFunc);return showText;}}public RelayCommand PassEvent { get; set; }private void ShowTextFunc(){MessageBox.Show("I am RealyCommand!");}#endregion

上面代码就是绑定无参事件,在View上可以通过如下方式绑定:

 <Button Content="绑定无参事件" Command="{Binding ShowText}" Height="23" HorizontalAlignment="Left" Margin="32,62,0,0" Name="button1" VerticalAlignment="Top" Width="141" />

绑定一个参数事件:

 #region Command with a parameter private RelayCommand<int> showValue;public RelayCommand<int> ShowValue{get{if (showValue == null)showValue = new RelayCommand<int>(x=>ShowValueFunc(x));return showValue;}}private int ShowValueFunc(int a){int c = a + 10;MessageBox.Show(c.ToString());return c;}#endregion

上面的代码部分就是绑定一个参数的事件定义,我们来驱动view层:

<Button Content="绑定一个参数事件" Command="{Binding ShowValue}" CommandParameter="{Binding ElementName=textBox1,Path=Text,Converter={StaticResource IntConverter}}" Height="23" HorizontalAlignment="Left" Margin="32,103,0,0" Name="button2" VerticalAlignment="Top" Width="141" />

需要说明的是,上面代码示例中,CommandParameter的值来自于textBox1的Text属性中。这个值加上10以后返回。

如果遇到用户输入不是数字的情况,则通过IntConverter方法将用户输入格式化,然后返回:

public class IntConverter:IValueConverter{public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture){int result;if(Int32.TryParse(value.ToString(),out result)){return result;}return "0";}public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture){throw new NotImplementedException();}}

绑定多个参数事件:

由于RelayCommand默认最多允许一个参数传递,所以这里如果想传递多个数据对象,只能够去构建自己的DTO了。

在Model文件夹新建一个BookItem类:

public class BookItem{public string BName { get; set; }public string BAuthor { get; set; }}

然后在ViewModel中进行如下控制:

 #region Command with multiple parametersprivate RelayCommand<BookItem> showBooks;public RelayCommand<BookItem> ShowBooks{get{if (showBooks == null)showBooks = new RelayCommand<BookItem>(x=>ShowBooksFunc(x));return showBooks;}}private void ShowBooksFunc(BookItem bookItem){MessageBox.Show(bookItem.BName+"|"+bookItem.BAuthor);}#endregion

驱动View层:

 <Button Command="{Binding ShowBooks}"  Content="绑定多个参数事件" Height="23" HorizontalAlignment="Left" Margin="32,141,0,0" Name="button3" VerticalAlignment="Top" Width="141" ><Button.CommandParameter><model:BookItem BName="testName" BAuthor="TestAuthor" ></model:BookItem></Button.CommandParameter></Button>

运行起来得时候,我们发现BookItem参数已经被自动赋值了。

ViewModel之间事件传递

最后需要讲解的是如何在ViewModel之间进行事件传递。由于在MVVMLight Toolkit中已经集成了Messenger对象,所以我们可以利用其很方便的进行事件传递,下面新建一个ChildWindow1.xaml子窗体,然后在ViewModelLocator中添加如下代码:

 public ChildViewModel Child{get{return ServiceLocator.Current.GetInstance<ChildViewModel>();}}

SimpleIoc.Default.Register<ChildViewModel>();

然后在ViewModel文件夹中新建一个ChildViewModel类,在其中添加如下代码:

 public class ChildViewModel:ViewModelBase{public ChildViewModel(){Messenger.Default.Register<BookItem>(this, message =>{MyText = message.BName + "|" + message.BAuthor;});}public string MyText { get; set; }}

由于我们传递的对象是从 MainViewModel到ChildViewModel,所以我们在MainViewModel中添加如下发送代码:

 #region Messenger communication cross pageprivate RelayCommand showChildWindow;public RelayCommand ShowChildWindow{get{if (showChildWindow == null)showChildWindow = new RelayCommand(ShowChildWindowFunc);return showChildWindow;}}private void ShowChildWindowFunc(){ChildWindow1 child = new ChildWindow1();child.Show();var bookItem = new BookItem() { BAuthor="TestAuthor",BName="TestName" };Messenger.Default.Send<BookItem>(bookItem);}#endregion

这样当运行起来的时候,我们就能看到效果了:

好了,暂时就到这里,后面我们再深入挖掘。

百度网盘下载

腾讯微盘下载

管窥MVVMLight Command参数绑定和事件传递相关推荐

  1. html下拉框传递参数,HTML通过事件传递参数到js详解及实例

    目标处理函数为selectAttr(test) 1.直接传递给定参数如:οnclick="selectAttr('1'); οnclick="selectAttr('a'); 2. ...

  2. 微信小程序学习5:小程序语法-事件绑定之给事件传递参数

    微信小程序学习5:小程序语法-事件绑定之给事件传递参数 前面一讲是关于事件绑定的,下面对事件绑定进行补充. 在用户触发事件,比如点击按钮时,我们往往要传递一下参数用来识别是那个按钮,因为一个界面往往不 ...

  3. WPF_MVVM实现Command绑定获取事件参数EventArgs

    这里主要实现的效果是窗体在关闭的时候,需要弹出消息框确认是否关闭,来拦截窗体的Closing事件,无需通过Loaded事件传递控件对象到ViewModel中. 1.创建WPF项目,需要引入System ...

  4. vue 点击事件传递多个参数_Vue子组件监听事件中传递参数的方法

    在子组件中,我们可以通过以下方式监听事件: v-on:click="$emit('funcName',a)" 如果需要传多个参数,可以通过以下方式: v-on:click=&quo ...

  5. WPF 使用Command,CommandParameter向 MVVM传递多个参数

    有的时候需要向ViewModel传递两个CommandParameter参数.需要实现一个Converter.然后就可以实现多个参数传递啦.本案例以MVVM为基础做的Demo.还有一个编写的按钮样式的 ...

  6. addeventlistener事件第三个参数_简析JavaScript 事件绑定、事件冒泡、事件捕获和事件执行顺序...

    这篇文章主要介绍了javaScript 事件绑定.事件冒泡.事件捕获和事件执行顺序整理总结的相关资料 (一)事件绑定的几种方式 javascript给DOM绑定事件处理函数总的来说有2种方式:在htm ...

  7. 组件:参数验证、组件:事件传递

    组件:参数验证 知识点 props:组件参数验证语法 组件的数据 为组件中接受到的变量进行逻辑验证. 综合例 <div id="myApp"><h1>身世之 ...

  8. JS与JQuery点击事件传递参数

    我们知道JS(javascript)是一种脚本语言,用于客户端web开发,常用来给html网页添加动态功能,是客户端运行的解释性语言. JQuery是对js的封装,简化了ajax和html的一款js框 ...

  9. Ant Design Vue 组件@chang绑定方法如何传递自定义参数

    Ant Design Vue 组件@chang绑定方法如何传递自定义参数 今天在写代码的时候遇到一个问题: 在嵌套标签中 外层使用了一个v-for循环去循环一个数组,当内层想要拿取index,并且使用 ...

最新文章

  1. lamp安装zabbix(全源码安装)
  2. 使用Python画一朵玫瑰花
  3. UNITY 优化之带Animator的Go.SetActive耗时问题,在手机上,这个问题似乎并不存在,因为优化了后手机上运行帧率并未明显提升...
  4. .netCore2.0 依赖注入
  5. 用python numpy实现幻方
  6. mysqld或mysqld_safe启动时必须放在第一位的参数(first argument)
  7. ie6-7下的li内有浮动元素后导致多出了4px的高度的bug
  8. python:urllib.error.URLError: <urlopen error [Errno 11004] getaddrinfo failed>
  9. C# .NET 爬虫抓取京东商城所有商品分类
  10. PCSHARE VIP 2005源代码
  11. 如何开始使用接口自动化测试脚本
  12. TOM企业邮箱,为你打造企业专属邮箱
  13. ios浏览器微信支付回调页面_iOS微信支付结果页面返回原程序按钮
  14. Java小型综合型练习——打字小游戏
  15. js chrome 富文本 恢复光标的办法
  16. tracert命令介绍
  17. 输入时刻time,计算出在time和time+1之间,时针和分针重合的时刻
  18. WebStorm破解补丁激活
  19. java数据库动态树形菜单_bootstrap treeview树形菜单 动态扩展 连数据库
  20. Tesin移动App测试突破1000万次,成为行业领跑者

热门文章

  1. Use a layout_width of 0dip instead of fill_parent for better performance
  2. android SQLite数据库的使用
  3. ScrollView’s handy trick--android:fillViewport=quot;truequot;
  4. Android Lint 去除重复资源 之 idea探究
  5. 记一次 javax.xml.soap.SOAPException:
  6. 通过composer安装阿里大于接口扩展
  7. MySQL存储过程和函数(一)
  8. mysql安装中出现的问题,
  9. ServletContextListener 解析用法
  10. 一步步学习操作系统(1)——参照ucos,在STM32上实现一个简单的多任务(“啰里啰嗦版”)...