原文:Mvvm Light Toolkit 入门

前言

之前学习UWP的时候就一直看到有关MVVM的资料但是一直没有系统的去学,最近正好有时间,特地来攻破这个点,顺便学习一下VS与GitHub的链接和MarkDown的语法。

下面的附件里有这篇博客里用到的Demo工程,我已经加上了比较详细的注释,可以帮助理解代码,欢迎点击查看。

MVVM简介

MVVM(Model-View-ViewModel)是一种程序模式,是MVP(Model-View-Presenter)模式与WPF结合的应用方式时发展演变过来的一种新型架构框架。它立足于原有MVP框架并且把WPF的新特性糅合进去,以应对客户日益复杂的需求变化。

如图,View就是视图,是呈现给用户的界面,它接受用户的交互,也为用户显示数据;ViewModel是视图模型,里面是显示逻辑,ViewModel与View进行绑定;然后是Model,也就是数据模型,主要用来给ViewModel提供数据,至于业务逻辑应该放在Model里还是ViewModel里似乎没有绝对的正确答案,两种方式都有人用。

MVVM模式有几大优点:

  1. 低耦合。视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的”View”上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
  2. 可重用性。你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑。
  3. 独立开发。开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计,使用Expression Blend可以很容易设计界面并生成xml代码。
  4. 可测试。界面素来是比较难于测试的,而现在测试可以针对ViewModel来写。

MVVM Light框架简介

MVVM Light是一种MVVM的实现。它不是唯一的一种实现,但它是现在大家公认的比较好的一个实现。

MVVM Light功能设计的非常灵活,非常注重实现,它实现了MVVM设计模式基础的框架如ViewModelBase类,实现了泛型Command< T >,这些都是MVVM基础。

MVVM Light有个创造性的设计就是消息通知(Messenger),这个设计非常的出色,让View与ViewModel的通信变的非常简单,实现了低耦合的设计原则。

一般我们说到MVVM Light都是指的MVVM Light Toolkit这个工具包,这个工具包的主要目的是加速 MVVM 应用程序在 Windows Universal、WPF、Silverlight、Xamarin.iOS、Xamarin.Android 和 Xamarin.Forms 的开发与创造。

MVVM Light Toolkit可以帮助我们从模型中分离视图,创建简洁和易于维护和扩展的应用程序。它还创建可测试的应用程序,并允许你有多个瘦用户界面层(这是更难自动测试的)。

该工具包在它创建的应用程序中特别强调“可设计” (即能够在Blend中打开和编辑用户界面),包括创建设计时数据,以使Blend使用者能够在和数据控件一起进行“可视化”的工作。

MVVM Light Toolkit 的安装

直接安装插件
打开VS,菜单栏选择:“工具” / “扩展和更新”,然后进入 “联机” / “Visual Studio MarketPlace” 选项卡,在搜索框中输入“mvvm light”,选择点击安装即可。
通过这个方法安装以后,新建工程的时候可以看到预设的几个模板:

如图,从上到下依次是UWP、安卓、iOS和WPF工程的模板,不过通过模板建立的UWP工程有点臃肿,我觉得算得上是一个Demo,各种特性都基本包括了,WPF工程倒是只有一个TextBlock在里面,比较简洁。

在项目中安装NuGet包
打开项目,在解决方案资源管理器中右击“引用”项,点击“管理NuGet程序包”,搜索“mvvm light”,安装“MVVMLightLibs”即可。
这个方法安装之后新建工程的时候没有模板

MVVM Light Toolkit 工程目录及文件

MVVM,自然就有Model、View和ViewModel三个部分了,以框架生成的的UWP模板为例,Model文件夹里面是数据模型,ViewModel文件夹里是视图模型,而视图则放在了根目录下面(当然你也可以新建一个View文件夹来存放视图)。

Design文件夹:
里面存放的是上面简介中提到的“设计时”数据,在VS Blend里打开项目时,运行时数据会填充到数据控件中,方便设计界面。
DesignDataService类,类似下面提到的DataService类。
Model文件夹:
IDataService接口里定义了一个名为GetData()的异步方法;

public interface IDataService
{
Task<DataItem> GetData();
}

DataService类实现了前面定义的方法,并返回了一个DataItem实例。

public Task<DataItem> GetData()
{
// Use this to connect to the actual data service(用来连接实际数据服务)
//
// Simulate by returning a DataItem
var item = new DataItem("Welcome to MVVM Light");
return Task.FromResult(item);
}
DataItem是数据模板。
ViewModel文件夹:
ViewModelLocator类包含了这个应用中所有ViewModel的静态引用并提供了绑定的进入点。并通过SimpleIoc这个容器实现了依赖注入。

使用ViewModelLocator的好处:

  1. View和ViewModel之间不再直接引用,而是通过ViewModelLocator关联。
  2. 储存在ViewModelLocator里的ViewModel类似与单例的存在,可以在全局引用绑定
  3. 避免了某些情况下频繁创建ViewModel,却未做好资源释放造成的内存泄漏。(并不是说所有ViewModel都必须放到ViewModelLocator里)

SimpleIoc的使用方法:

  1. 将自己的类注册到SimpleIoc

    SimpleIoc.Default.Register(()=>new MyClass());
  2. 把MainViewModel也注册到SimpleIoc

    SimpleIoc.Default.Register<MainViewModel>();
  3. 在Main属性中通过ServiceLocator.Current.GetInstance()方法获取实例

    public MainViewModel Main => ServiceLocator.Current.GetInstance<MainViewModel>();
  4. 在MainViewModel的构造函数中匹配MyClass类

    public MainViewModel(MyClass data)
    {
    WelcomeTitle = data.Name;
    }

MainViewModel类则是与MainPage相对应的ViewModel,通过绑定实现MainPage中的各种行为。

App.xaml文件:
将ViewModelLocator作为资源添加到全局的Application.Resources里。

<Application.Resources>
<!-- 将ViewModelLocator作为资源添加到全局的Application.Resources里 -->
<!--Global View Model Locator-->
<vm:ViewModelLocator x:Key="Locator"
d:IsDataSource="True" />
</Application.Resources>
MainPage.xaml文件:
第11行,以StaticResource的形式获取ViewModelLocator实例的资源,并Binding到了页面的DataContext属性。

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

通过绑定控件的Command(或者Behavior)属性实现各种点击后的功能。

<Button Content="Increment counter"
HorizontalAlignment="Stretch"
Margin="0,0,0,20"
FontSize="24"
Command="{Binding IncrementCommand, Mode=OneWay}"
Foreground="White" />
SecondPage.xaml文件:
非常简单,没有用到MVVM模式,采用默认的Code Behind方式实现显示和页面返回。

MVVM Light的程序集和命名空间

GalaSoft.MvvmLight.dll程序集

GalaSoft.MvvmLight 命名空间

最顶层的命名空间,包含了MvvmLight的主体,最核心的功能都在这里。

  • ICleanup

    实现该接口的ViewModel需要在Cleanup方法中释放资源,特别是-=event。

  • ObservableObject

    该类实现了INotifyPropertyChanged接口,定义了一个可通知的对象基类,供ViewModelBase继承。

  • ViewModelBase

    继承自ObsevableObject,ICleanup。

    将作为MvvmLight框架下使用的ViewModel的基类。

    主要提供Set和RaisePropertyChanged供外部使用。同时会在Cleanup方法里,Unregister该实例的所有MvvmLight Messager(在GalaSoft.MvvmLight.Messaging命名空间内定义)。

  • RelayCommand

    提供了一个ICommand接口的实现

  • RelayCommand< T >

    提供了ICommand接口的泛型实现

GalaSoft.MvvmLight.Helpers 命名空间

MvvmLight框架内部使用的一些辅助类,框架的使用者不直接接触该命名空间。

GalaSoft.MvvmLight.Messaging 命名空间

消息类命名空间,提供全局的消息通知。

GalaSoft.MvvmLight.Views 命名空间

和View结合较紧密,ViewModel通过依赖该命名空间下的类,来避免直接引用View,用以解耦代码对具体的平台的依赖。

  • IDialogService

    对系统弹框消息的抽象。

    针对具体平台会在GalaSoft.MvvmLight.Platform程序集里分别实现

  • INavigationService

    对页面导航的抽象,不同平台会有不同实现。

GalaSoft.MvvmLight.Extras程序集

GalaSoft.MvvmLight.Ioc 命名空间

依赖注入使用的容器放在这个命名空间。

  • ISimpleIoc

    IOC(Inverse Of Control)控制反转,也就是依赖注入(Dependency Injection),简单可以理解为一个托管的容器,替你创建和管理对象。在MVVM中,一般是ViewModel.

  • PreferredConstructorAttribute

    该类继承自Attribute,不常用。

    当ViewModel存在一个以上的构造函数时,可以通过他来指定SimpleIoc默认调用的构造函数。

  • SimpleIoc

    ISimpleIoc接口的实现。功能简单实用。

GalaSoft.MvvmLight.Platform程序集

依赖平台具体实现的功能会放到这个程序集里

GalaSoft.MvvmLight.Threading 命名空间

  • DispatcherHelper

    非UI线程操作UI线程时用到的帮助类,已针对各平台不同的写法做了封装。

GalaSoft.MvvmLight.Views 命名空间

  • DialogService

    IDialogService接口的实现。

  • NavigationService

    INavigationService接口的实现。

附件

上面用到的Demo(已详细注释)

参考

MvvmLight框架使用入门(一)

MvvmLight框架使用入门(二)

MVVM Light Toolkit

Mvvm Light Toolkit 入门的更多相关文章

  1. Mvvm Light Toolkit for WPF/Silverlight系列之搭建mvvmlight开发框架

    Mvvm Light Toolkit for WPF/Silverlight系列之搭建mvvmlight开发框架   本章节,我将通过示例介绍如何搭建mvvmlight开发环境.示例中的我会针对wpf ...

  2. MVVM Light Toolkit使用指南

    原文:MVVM Light Toolkit使用指南 原文地址:  https://blog.csdn.net/ldld1717/article/details/77040077 概述 MVVM Lig ...

  3. MvvmLight学习篇—— Mvvm Light Toolkit for wpf/silverlight系列(导航)

    系列一:看的迷迷糊糊的 一.Mvvm Light Toolkit for wpf/silverlight系列之准备工作 二.Mvvm Light Toolkit for wpf/silverlight ...

  4. How to install MVVM Light Toolkit via NuGet

    Here is how you can install MVVM Light Toolkit  via NuGet in an easy way using only Visual Studio. S ...

  5. MVVM Light 新手入门(1):准备阶段

    1.新建WPF空白项目. 2.NuGet 程序包中安装 3.根据MVVM分层结构,建立包含Model.View.ViewModel三层文件夹 如图: 1.View负责前端展示,与ViewModel进行 ...

  6. MVVM Light 新手入门(3) :ViewModel / Model 中定义“事件” ,并在View中调用 (无参数调用)

    今天学习MVVM架构中“事件”的添加并调用,特记录如下,学习资料均来自于网络,特别感谢翁智华 的 利刃 MVVMLight 6:命令基础 在MVVM Light框架中,事件是WPF应用程序中UI与后台 ...

  7. MVVM Light 新手入门(2) :ViewModel / Model 中定义“属性” ,并在View中调用

    今天学习MVVM架构中“属性”的添加并调用,特记录如下,学习资料均来自于网络,特别感谢翁智华的利刃 MVVMLight系列. 一个窗口的基本模型如下: View(视图) -> ViewModel ...

  8. MVVM Light须要注意的10个问题

    MVVM Light须要注意的10个问题 从使用XAML技术基础開始(实际上并非非常久曾经).我便关注MVVM(Model – View – ViewModel)模式.偶然接触到MVVM Light不 ...

  9. MVVM Light 笔记

    4.关于子视图, MVVMLight Using Two Views:http://www.codeproject.com/Articles/323187/MVVMLight-Using-Two-Vi ...

随机推荐

  1. HDU 1243 反恐训练营 (动态规划求最长公共子序列)

    反恐训练营 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Subm ...

  2. Snmp常用oid

    http://blog.csdn.net/youngqj/article/details/7311849 系统参数(1.3.6.1.2.1.1)   OID 描述 备注 请求方式 .1.3.6.1.2 ...

  3. 基于 Android NDK 的学习之旅-----Java 调用C

    随便谈谈为什么要Java调用C 吧: 我认为: 1.  有些公司开发Android项目的时候, 许多组件功能可能是C中已经实现了,所以我们没必要同样的功能又在java中实现一遍.例如我之前做的一个项目 ...

  4. Java环境搭建若干问题

    0.总体说明   本次搭建环境,为了偷懒,使用的是,阿里云镜像.   自带了Nginx.Tomcat.JDK等.   比较坑爹的是,虽然镜像带了很多安装好的软件,但是也有各种问题,比如它修改了tomc ...

  5. 【a402】十进制数转换为八进制数

    Time Limit: 1 second Memory Limit: 32 MB [问题描述] 用递归算法把任一给定的十进制正整数m(m≤32000)转换成八进制数输出.(要求:同学在做本题时用递归和 ...

  6. Javascript中eval解析的json的几种用法

    eval解析json字符串可用的三种方式都可以实现... <!DOCTYPE html> <html> <head> <meta charset=" ...

  7. 窗体背景的绘制(Windows窗体每次都会重绘其窗体背景,所以我们可以通过拦截窗体重绘背景的消息(WM_ERASEBKGND),并自定义方法来实现重绘窗体背景)

    核心思想:由于Windows窗体每次都会重绘其窗体背景,所以我们可以通过拦截窗体重绘背景的消息(WM_ERASEBKGND),并自定义方法来实现重绘窗体背景.通过TImage组件也可以实现,但是重写W ...

  8. 深度剖析:最新云端开发工具如何实现敏捷+DevOps开发落地

    相信很多软件开发人员们对今年国内新兴的云端开发工具——华为软件开发云都有耳闻,有些人可能还免费体验过,由于它5人以下的团队是免费使用的,很庆幸本人的这个项目正好5个人,就注册使用了.下面就自己的使用心 ...

  9. 报错:javax.servlet.jsp.PageContext cannot be resolved to a type;javax.servlet.jsp.JspException cannot be resolved to a type

    Multiple annotations found at this line: - javax.servlet.jsp.PageContext cannot be resolved to a typ ...

  10. 学术论文写作的 paper、code 资源

    (机器学习/计算机视觉/深度学习)代码 0. 核心期刊 Best paper awards at - CV NIPS: JMLR COLT & ICML(每年度的官网) 1. Computin ...