一、MVVM分层概述

MVVM中,各个部分的职责如下:

Model:负责数据实体的结构处理,与ViewModel进行交互;

View:负责界面显示,与ViewModel进行数据和命令的交互;
ViewModel:负责前端视图业务级别的逻辑结构组织,并将其反馈给前端。
 
二、MVVMLight框架初探
通过NuGet安装MVVM Light 框架后,我们新建的Wpf项目中会自动生成一个ViewModel文件夹,里面有MainViewModel.cs和ViewModelLocator.cs两个文件。
下面我们就首先分析下这两个文件的内容:
MainViewModel.cs文件分析:
MainViewModel.cs文件中只有一个类MainViewModel,该类是主窗口MainWindow对应的ViewModel,继承自类ViewModelBase
ViewModelBase类又继承类ObservableObject,同时实现ICleanup接口
ObservableObject类实现INotifyPropertyChanged接口,用于通知属性的改变
由此分析,我们可以得出以下一般结论:
当我们定义一个自己的ViewModel时,一般让自定义ViewModel继承自ViewModelBase类,这样当ViewModel中属性发生变化的时候,就可以自动通知对应的VIew。
 
ViewModelLocator.cs文件分析:
ViewModelLocator.cs文件中只有一个ViewModelLocator类,类中包括一个构造函数、一个类型为MainViewModel的Main属性、以及一个静态的Cleanup函数。
 

 public class ViewModelLocator
{
/// <summary>
/// Initializes a new instance of the ViewModelLocator class.
/// </summary>
public ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default); ////if (ViewModelBase.IsInDesignModeStatic)
////{
//// // Create design time view services and models
//// SimpleIoc.Default.Register<IDataService, DesignDataService>();
////}
////else
////{
//// // Create run time view services and models
//// SimpleIoc.Default.Register<IDataService, DataService>();
////} SimpleIoc.Default.Register<MainViewModel>();
} public MainViewModel Main
{
get
{
return ServiceLocator.Current.GetInstance<MainViewModel>();
}
} public static void Cleanup()
{
// TODO Clear the ViewModels
}
}

在构造函数中,创建了一个SimpleIoc类型的单实例,用于注册ViewModel,然后用ServiceLocator对这个SimpleIoc类型的单实例进行包裹,方便统一管理。
观察App.xaml文件,我们会发现ViewModelLocator类被生成资源字典并加入到了全局资源,所以每次App初始化的时候,就会去初始化ViewModelLocator类。

实际上,他是一个很基本的视图模型注入器,在构造器中把使用到的ViewModel统一注册,并生成单一实例。然后使用属性把它暴露出来,每当我们访问属性的时候,就会返回相应的ViewModel实例。

<Application x:Class="MvvmLightDemo.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MvvmLightDemo" StartupUri="MainWindow.xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
d1p1:Ignorable="d" xmlns:d1p1="http://schemas.openxmlformats.org/markup-compatibility/2006">
<Application.Resources>
<ResourceDictionary>
<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" xmlns:vm="clr-namespace:MvvmLightDemo.ViewModel" />
</ResourceDictionary>
</Application.Resources>
</Application>

由此分析,我们可以得出以下一般结论:

当我们自定义一个ViewModel的时候,就可以在ViewModelLocator类的构造函数中对ViewModel进行注册,然后在该类中定义一个属性,用于返回我们的自定义ViewModel

三、MVVMLight框架初探实战Demo

在建立一个MVVMLight框架的Wpf工程后,我们再在工程下建立Model和View(该文件夹在本Demo中暂时不用,我们只使用主窗口)文件夹,VIewModel文件夹框架已经自动帮我们建立了,无需再创建。

1)在Model文件夹下建立一个WelcomeModel .cs文件,文件内容如下:

using GalaSoft.MvvmLight;

namespace MvvmLightDemo1.Model
{
public class WelcomeModel : ObservableObject
{
private string welcomeMsg;
public string WelcomeMsg
{
get { return welcomeMsg; }
set { welcomeMsg = value; RaisePropertyChanged(() => WelcomeMsg); }
}
} }

类WelcomeModel继承自类ObservableObject,并包含一个简单的string类型的WelcomeMsg属性,用于显示欢迎信息。
类ObservableObject位于GalaSoft.MvvmLight命名空间,实现INotifyPropertyChanged接口,通过触发PropertyChanged事件达到通知UI属性更改的目的。

所以,我们在定义实体对象的时候,只需要在属性的set块中调用RaisePropertyChanged(PropertyName)就可以进行属性更改通知,实现与UI的交互。

2)在MainViewModel中定义一个WelcomeModel类型的属性WelcomeModel,并在构造函数中对该属性进行初始化。

using GalaSoft.MvvmLight;
using MvvmLightDemo1.Model; namespace MvvmLightDemo1.ViewModel
{
/// <summary>
/// This class contains properties that the main View can data bind to.
/// <para>
/// Use the <strong>mvvminpc</strong> snippet to add bindable properties to this ViewModel.
/// </para>
/// <para>
/// You can also use Blend to data bind with the tool's support.
/// </para>
/// <para>
/// See http://www.galasoft.ch/mvvm
/// </para>
/// </summary>
public class MainViewModel : ViewModelBase
{
private WelcomeModel welcomeModel;
public WelcomeModel WelcomeModel
{
get { return welcomeModel; }
set { welcomeModel = value; RaisePropertyChanged(() => WelcomeModel); }
}
/// <summary>
/// Initializes a new instance of the MainViewModel class.
/// </summary>
public MainViewModel()
{
WelcomeModel = new WelcomeModel() { WelcomeMsg = "Welcome to MVVMLight World!" };
}
}
}

3)修改主窗口

<Window x:Class="MvvmLightDemo1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MvvmLightDemo1"
mc:Ignorable="d"
Title="MVVMLIghtDemo1" Height="350" Width="525" Background="#FF256795">
<Window.DataContext>
<Binding Path="Main" Source="{StaticResource Locator}"></Binding>
</Window.DataContext>
<Grid>
<StackPanel VerticalAlignment="Top" HorizontalAlignment="Center" >
<TextBlock Text="{Binding WelcomeModel.WelcomeMsg}" FontSize="28" Foreground="#FF128738"></TextBlock>
</StackPanel>
</Grid>
</Window>

TextBlock 绑定了 WelcomeModel中的WelcomeMsg,用于显示欢迎信息。

然后,我们通过ViewModelLocator的Main属性返回MainViewModel,将它赋值给MainWindow的DataContext属性,完成VIew和ViewModel的关联。

     <Window.DataContext>
        <Binding Path="Main" Source="{StaticResource Locator}"></Binding>
    </Window.DataContext>
Key为Locator的类型为ViewModelLocator的资源在App.xaml中被声明,是一个全局资源。
App.xaml文件内容如下:
<Application x:Class="MvvmLightDemo1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MvvmLightDemo1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
d1p1:Ignorable="d" xmlns:d1p1="http://schemas.openxmlformats.org/markup-compatibility/2006"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" xmlns:vm="clr-namespace:MvvmLightDemo1.ViewModel" />
</ResourceDictionary>
</Application.Resources>
</Application>

ViewModelLocator.cs文件内容如下:

/*
In App.xaml:
<Application.Resources>
<vm:ViewModelLocator xmlns:vm="clr-namespace:MvvmLightDemo1"
x:Key="Locator" />
</Application.Resources> In the View:
DataContext="{Binding Source={StaticResource Locator}, Path=ViewModelName}" You can also use Blend to do all this with the tool's support.
See http://www.galasoft.ch/mvvm
*/ using CommonServiceLocator;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Ioc; namespace MvvmLightDemo1.ViewModel
{
/// <summary>
/// This class contains static references to all the view models in the
/// application and provides an entry point for the bindings.
/// </summary>
public class ViewModelLocator
{
/// <summary>
/// Initializes a new instance of the ViewModelLocator class.
/// </summary>
public ViewModelLocator()
{
ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default); ////if (ViewModelBase.IsInDesignModeStatic)
////{
//// // Create design time view services and models
//// SimpleIoc.Default.Register<IDataService, DesignDataService>();
////}
////else
////{
//// // Create run time view services and models
//// SimpleIoc.Default.Register<IDataService, DataService>();
////} SimpleIoc.Default.Register<MainViewModel>();
} public MainViewModel Main
{
get
{
return ServiceLocator.Current.GetInstance<MainViewModel>();
}
} public static void Cleanup()
{
// TODO Clear the ViewModels
}
}
}

至此,一个初级的MVVMLight项目就构建完成了。
运行结果如下:

MVVMLight学习笔记(二)---MVVMLight框架初探的更多相关文章

  1. [Firefly引擎][学习笔记二][已完结]卡牌游戏开发模型的设计

    源地址:http://bbs.9miao.com/thread-44603-1-1.html 在此补充一下Socket的验证机制:socket登陆验证.会采用session会话超时的机制做心跳接口验证 ...

  2. muduo学习笔记(二)Reactor关键结构

    目录 muduo学习笔记(二)Reactor关键结构 Reactor简述 什么是Reactor Reactor模型的优缺点 poll简述 poll使用样例 muduo Reactor关键结构 Chan ...

  3. qml学习笔记(二):可视化元素基类Item详解(上半场anchors等等)

    原博主博客地址:http://blog.csdn.net/qq21497936本文章博客地址:http://blog.csdn.net/qq21497936/article/details/78516 ...

  4. 转)delphi chrome cef3 控件学习笔记 (二)

    (转)delphi chrome cef3 控件学习笔记 (二) https://blog.csdn.net/risesoft2012/article/details/51260832 原创 2016 ...

  5. WPF的Binding学习笔记(二)

    原文: http://www.cnblogs.com/pasoraku/archive/2012/10/25/2738428.htmlWPF的Binding学习笔记(二) 上次学了点点Binding的 ...

  6. AJax 学习笔记二(onreadystatechange的作用)

    AJax 学习笔记二(onreadystatechange的作用) 当发送一个请求后,客户端无法确定什么时候会完成这个请求,所以需要用事件机制来捕获请求的状态XMLHttpRequest对象提供了on ...

  7. JMX学习笔记(二)-Notification

    Notification通知,也可理解为消息,有通知,必然有发送通知的广播,JMX这里采用了一种订阅的方式,类似于观察者模式,注册一个观察者到广播里,当有通知时,广播通过调用观察者,逐一通知. 这里写 ...

  8. java之jvm学习笔记二(类装载器的体系结构)

    java的class只在需要的时候才内转载入内存,并由java虚拟机的执行引擎来执行,而执行引擎从总的来说主要的执行方式分为四种, 第一种,一次性解释代码,也就是当字节码转载到内存后,每次需要都会重新 ...

  9. Java IO学习笔记二

    Java IO学习笔记二 流的概念 在程序中所有的数据都是以流的方式进行传输或保存的,程序需要数据的时候要使用输入流读取数据,而当程序需要将一些数据保存起来的时候,就要使用输出流完成. 程序中的输入输 ...

  10. 《SQL必知必会》学习笔记二)

    <SQL必知必会>学习笔记(二) 咱们接着上一篇的内容继续.这一篇主要回顾子查询,联合查询,复制表这三类内容. 上一部分基本上都是简单的Select查询,即从单个数据库表中检索数据的单条语 ...

随机推荐

  1. 常见内部排序算法对比分析及C++ 实现代码

    内部排序是指在排序期间数据元素全部存放在内存的排序.外部排序是指在排序期间全部元素的个数过多,不能同时存放在内存,必须根据排序过程的要求,不断在内存和外存之间移动的排序.本次主要介绍常见的内部排序算法 ...

  2. Java基础00-反射35

    1. 类加载器 深入理解java类加载器类加载器 1.1 类加载 类加载或类初始化的三个步骤:类的加载.类的连接.类的初始化 加载:类加载过程的一个阶段:通过一个类的完全限定查找此类字节码文件,并利用 ...

  3. jumpserver 用户,系统用户和管理用户 普通用户和特权用户 区别

    前言 现在很多公司都有在用Jumpserver跳板机 有很多人一直对jumpserver的各种用户还不是很了解 当你了解了这几个概念了之后,就能更好的灵活的运用到分配权限当中去. 下面我们一个一个的说 ...

  4. POJ3190 - 优先队列 贪心

    POJ3190 将所有牛从小到大排序然后用优先队列(小根堆)依次记录插入的牛的结束时间,如果插入牛时起始时间大于首元素,ans不增加并弹出首元素. 挺简单的.那么为什么我会写(水)这篇博客呢? #in ...

  5. odoo12学习之javascript-----2

    用例子:Creating a new field widget 这可能是一个非常常见的用例:我们希望以非常具体(可能依赖于业务)的方式在表单视图中显示一些信息. 例如,假设我们要根据某些业务条件更改文 ...

  6. 第二十二篇 -- 事件与信号(自定义label信号的双击功能)

    在第六篇中已经学习过了自定义信号的相关内容了,那一篇中讲的是自定义类中的自定义信号,类和信号都是自己定义的.那么今天想要学习的是事件处理和信号的关系.如同Label标签,它本身有很多的信号,但是它没有 ...

  7. mysql 占用90%多的CPU,解决思路

    网站打开很慢,爆出了连接数据库的错误,进入服务器,top 看了下,mysql占用cpu 基本维持在90以上: mysql> show variables like '%slow%';      ...

  8. vue实现单点登录的N种方式

    最近项目停工了,RageFrame的学习暂时告一段落,这一篇给大家分享下有关单点登录的相关知识,并提供一些demo给大家参考,希望对想了解的朋友有一些帮助. 话不多说,先上原理(借鉴地址:https: ...

  9. azure获取vm运行状态

    az vm list -d -o json --query "[?name=='vm-name']" | jq '.[0].powerState' 输出vm信息 az vm lis ...

  10. 剑指 Offer 32 - II. 从上到下打印二叉树 II

    剑指 Offer 32 - II. 从上到下打印二叉树 II 从上到下按层打印二叉树,同一层的节点按从左到右的顺序打印,每一层打印到一行. 例如: 给定二叉树: [3,9,20,null,null,1 ...