zoukankan      html  css  js  c++  java
  • MVVMLight使用前观看

    我想,现在已经有不少朋友在项目中使用了MVVMLight了吧,如果你正在做WPF,Silverlight,Windows Phone的开发,那么,你有十分必要的理由了解MVVM和MVVMLight。我写这篇文章的目的,是给大家做一个总结,以便更多的朋友了解并掌握MVVM。

    首先,要说一下MVVM的概念。MVVM严格来说,并不是一种框架,而是一个设计的模式吧。与它有关的设计模式还有MVC (现在广泛用于Web应用中),以及MVP(之前有用过在Windows Forms和WPF中)

    如果你希望对MVVM有更加感性地认识,我推荐你看下面这篇文章。

    这篇文章写得实在太好了,我很欣赏这样的技术人才,能把一个抽象问题有层次地讲清楚。(我强烈建议对MVVM的概念了解不深的朋友,认真读这篇文章,而不要急于用MVVMLight,因为MVVM是一种模式,而MVVMLight只是其中一种具体的实现)

    然后,我要说一下MVVMLight吧,刚才说了,它是一种MVVM的实现。自然它不是唯一的一种实现,但现在大家公认的是,它是比较好的一个实现。就我个人的体会来说,我以前用过微软提供的Prism中的MVVM特性,但老实说,可能Prism的目标太大了,所以在MVVM这个具体的点上,实在不是那么好用。

    值得一说的是,从使用Prism转换到使用MVVMLight过程相当简单,如果有类似情况的朋友,不要有什么顾虑。我这里不是说Prism不好,它与Mvvmlight严格来说,不是一个重量级的产品。MVVMLight专注与MVVM的实现,自然更加灵活

    接下来,我认为要学习MVVMLight最好的Quick start,就是作者自己写的这个网页

    通过这个文章,我们可以很清楚地了解MVVMLight的设计思路和包含的有关组件,无需太多补充,文章浅显易懂,确实是我们要学习的一个榜样

    请注意,我这篇文章并非逐一讲解MVVMLight的细节功能使用,我主要提一些重点,并且分享一些我的看法和观点,当然这仅是我一家之言,不见得完全正确。

    事实上针对如何使用的方面,已经有不少文章了,大家可以参考

    http://zzk.cnblogs.com/s?w=mvvmlight

    另外一方面,我觉得大家其实要自己多动手才会有实际的收获。MVVMLight使用并不难,在使用中大家可以领会到更多。

    实际上,我们经常谈论MVVMLight的时候,其实谈的是MVVMLight Toolkit,它主要是为了更加方便开发人员使用MVVMLight,它会在本地的GAC(Global Assembly Cache)中分别安装针对WPF,Silverlight,Windows Phone的Assembly(分别各自有两个Assembly),并且在Visual Studio中添加相应的项目以及项模板,更加贴心的一点是,它还提供了几个代码段。

    有的朋友可能会问,那么MVVMLight到底是什么呢?呃,MVVMLight嘛,就是MVVMLight Toolkit的名称啦 Be right back,有点绕对吧,放松点,不要那么较真嘛

    那么,如果你像我一样,不安装MVVMLight Toolkit,如何使用MVVMLight呢?实际上很简单,我更加习惯于使用nuget package 来获取最新的MVVMLight的Library,并将它们添加到项目中来。

    你可以通过这个菜单打开nuget package explorer,如下图所示,然后,你可以在Online里面搜索MVVMLight,或者像我这样在Recent package中直接就可以Install。(nuget package是会被缓存在本地的,所以即便没有链接到网络,也可以正常使用)

    既然可以缓存在本地,那么其实和安装到GAC是没有太大区别的,不是吗?

    而且用这种方式还有一个好处,你总是可以得到最新的版本,因为nuget package是自动有更新提示的。而如果你是用Toolkit的话,则得不到更新的提示。(据可靠消息,MVVMLight将很快有4.0这个版本)

    很好,你现在已经知道如何将MVVMLight添加到项目中,接下来就是该让它发挥威力的时候啦。大家一定要理解MVVM的两个核心目标

    1.让UI界面与逻辑能够很好地分离又协同工作。

    2.让逻辑代码更具有可测试性。

    我们先来说说分离并协同这个目标,在MVVMLight中主要通过什么实现的呢?它提供了ViewModelBase这个基类,可以让我们很方便地编写ViewModel。从下面的截图可以看出,它提供了很多有用的特性,例如判断是否在设计状态(IsInDesignMode),以及触发属性更改通知(RaisePropertyChanged),尤其是后者,这可以说是MVVM的根基,为什么这么说呢?UI与逻辑的分离并且协同工作,关键就在于WPF和Silverlight有强大的数据绑定机制,而数据绑定机制之所以能够强大,就是因为WPF和Silverlight中引入的依赖属性(Dependency Property)的机制,而依赖属性,区别于普通属性的最重要一点就是既可以有单向绑定,也可以有双向绑定,而且属性更改之后,可以通知到所有绑定目标上面。

    除了很好的支持绑定,UI与逻辑分离并协作的另外一个重要机制,就是命令(command)机制。在MVVMLight中,它提供了两个基本的命令:RelayCommand和RelayCommand<T>

    这两个命令其实没有本质区别,只不过后者是支持泛型的一个参数的,就是可以从命令源接受参数数据。

    需要注意的是,这两个命令只适合绑定在基于按钮的Click事件上面。例如Button,HyperlinkButton是最常见的。例如下面的例子

    这个绑定的意思,其实就是说,当这个Button被点击了之后,调用ViewModel中的SaveCommand

    如果需要传递参数过去呢,就是下面这样啦。我举了两个例子,第一个例子参数是一个常数,而第二个例子参数是一个绑定值,这都是允许的

    但问题是,如果我要绑定其他事件呢?例如MouseMove事件,该怎么办呢?在MvvmLight.Extras这个程序集里面,单独又给出了一个Command绑定方式,叫EventToCommand,顾名思义,它可以将任何事件绑定到一个命令

    要使用这个略微麻烦一些,请看下面的例子

    所以,绑定(尤其是双向绑定)和命令是MVVM的精髓,但实际要认真讲起来,MVVMLight这方面实现得其实也没有什么特别突出的,其他一些框架也都是这么做的。以前没有这些框架之前,我们也是这么写的,无非是代码会多一些而已。

    有童鞋可能会说了,属性绑定我们可以理解,但为嘛要这么麻烦去绑定命令呢?直接在xaml.cs里面写不就完了吗?请注意,MVVM的一个目标就是让xaml.cs代码中尽量少,极端的情况是没有任何用户代码。这样才能实现UI与逻辑的分离,所以尽可能地用Command来做。

    这里我也分享我的个人经验,一定会有的时候,你没有办法全部用Command,而不在xaml.cs中写任何代码。那个时候,你也大可像我一样,将代码写一些在xaml.cs中也无妨。典型的情况,是希望在视图里面接受消息(下面就要讲到),并且更新界面的一些效果,例如启动动画。这里面是一个度的把握,并无绝对的好坏。我已经看到有人心领神会地点头了,所谓随机应变,大家要有一定的灵活性。

    不过,Mvvmlight的一个创造性的设计,是它的Message(消息)机制它让View和ViewModel,以及ViewModel之间通讯变得相当方便,甚至神奇。我相当欣赏这个设计,这是Mvvmlight之所以称为Mvvmlight的原因。

    具体来说,它提供了一个Messenger类型,可以用来发送和接收消息,它还提供了默认的几种消息类型。

    Messenger class (and diverse message types) to be used to communicate within the application. Recipients only receive the message types that they register for. Additionally, a target type can be specified, in which case the message will only be transmitted if the recipient's type matches the target parameter.
    Messages can be anything from simple values to complex objects. You can also use specialized message types, or create your own types deriving from them.
    More information about the Messenger class.

    • MessageBase: A simple message class, carrying optional information about the message's sender.
    • GenericMessage<T>: A simple message with a Content property of type T.
    • NotificationMessage: Used to send a notification (as a string) to a recipient. For example, save your notifications as constant in a Notifications class, and then send Notifications.Save to a recipient.
    • NotificationMessage<T>: Same as above, but with a generic Content property. Can be used to pass a parameter to the recipient together with the notification.
    • NotificationMessageAction: Sends a notification to a recipient and allows the recipient to call the sender back.
    • NotificationMessageAction<T>: Sends a notification to a recipient and allows the recipient to call the sender back with a generic parameter.
    • DialogMessage: Used to request that a recipient (typically a View) displays a dialog, and passes the result back to the caller (using a callback). The recipient can choose how to display the dialog, either with a standard MessageBox, with a custom popup, etc…
    • PropertyChangedMessage<T>: Used to broadcast that a property changed in the sender. Fulfills the same purpose than the PropertyChanged event, but in a less tight way.

    一个稍微具体一点的例子,请参考

     

  • 相关阅读:
    在thinkphp中批量生成Word并压缩打包下载
    使用phpExcel实现Excel数据的导入导出(完全步骤)
    HTML的几种触发
    IOS上iframe的滚动条失效的解决办法。
    VC6下安装与配置OpenCV1.0
    VS2010+Opencv2.4.0的配置攻略
    could not find the main class
    Makefile 教程
    第一个小程序——显示图像
    自建CDib类库
  • 原文地址:https://www.cnblogs.com/dachuang/p/15606894.html
Copyright © 2011-2022 走看看