本篇我们着重介绍ViewModelBase,演示Set和RaisePropertyChanged方法的使用,以及就Cleanup方法释放资源展开讨论。

ICleanup

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

ObservableObject

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

ViewModelBase

继承自ObservableObject,   ICleanup。将作为MvvmLight框架下使用的ViewModel的基类。主要提供Set和RaisePropertyChanged供外部使用。同时会在Cleanup方法里,Unregister该实例的所有的MvvmLight Messenger(在GalaSoft.MvvmLight.Messaging命名空间定义)

  以上是第一篇里给出的表格,ViewModelBase是MvvmLight里非常重要的一个基类,理论上使用MvvmLight你所有的ViewModel都需要继承该类(当然你也可以不继承,那你还用啥MvvmLight?啥?只用RelayCommand?给跪了……)

  我们先看一下最基本的Set和RaisePropertyChanged方法的使用:

        private string title;

        public string Title
{
get { return title; }
set { Set(ref title , value); }
} private string text; public string Text
{
get { return text; }
set
{
text = value;
RaisePropertyChanged("Text");
RaisePropertyChanged("TitleAndText");
}
} public string TitleAndText
{
get
{
return title + text;
}
}

  Set方法会再属性赋值时自动为你调用RaisePropertyChanged进行通知。当然你也可以手动调用RaisePropertyChanged方法。

  MvvmLight的源代码如下,将可复用的逻辑提取封装,减少了我们搬砖时的工作量:

        protected bool Set<T>(
ref T field,
T newValue = default(T),
bool broadcast = false,
[CallerMemberName] string propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(field, newValue))
{
return false;
}
#if !PORTABLE
RaisePropertyChanging(propertyName);
#endif
var oldValue = field;
field = newValue; RaisePropertyChanged(propertyName, oldValue, field, broadcast);
return true;
}

  Cleanup是一个非常重要的方法。当前Page在OnNavigatedFrom时,应该要释放不再需要的资源,特别是-= event,Unregister掉MvvmLight的Messenger。

  在继承ViewModelBase的子类ViewModel里调用base.Cleanup();会自动释放掉当前ViewModel注册的Messenger

  ViewModelBase里的Cleanup方法:

        public virtual void Cleanup()
{
MessengerInstance.Unregister(this);
}

  所以一般ViewModel的OnNavigatedFrom方法看上去都是这个样子:

        public void OnNavigatedFrom(object obj)
{
base.Cleanup();
this.xxxxEvent -= xxxxHandler;
}

  什么什么,你说ViewModel是没有OnNavigatedFrom方法的?确实是没有的,但是我们这里给需要处理导航事件的ViewModel都实现了INavigable接口:

    public interface INavigable
{
void OnNavigatedFrom(object obj); void OnNavigatedTo(object obj);
}

  然后呢,override需要处理导航事件的Page的相应方法,调用ViewModel里的NavigatedFrom、NavigatedTo方法,传递参数,把处理的逻辑放到ViewModel中:

    public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
} protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
var navigable = DataContext as INavigable;
navigable.OnNavigatedTo(e.Parameter);
} protected override void OnNavigatedFrom(NavigationEventArgs e)
{
base.OnNavigatedFrom(e);
var navigable = DataContext as INavigable;
navigable.OnNavigatedFrom(e.Parameter);
}
}

  看到这里,是不是觉得释放资源什么的也是一件非常的简单的事情呢?但是骚年!Too young too simple, sometimes naive!仅仅这样就够了吗?我们需要再回到Cleanup方法,既然ViewModel可以通过OnNavigatedFrom来释放资源,但如果ViewModel并没有,或者说不需要导航事件,又该如何处理呢。例如某个MainPage对应的MainViewModel中存在一个ContactViewModel的列表:

    public class MainViewModel : ViewModelBase, INavigable
{
ObservableCollection<ContactViewModel> ContactList { get; set; }

  而ContactViewModel仅仅是对Contact数据对象做的封装,并不存在导航事件。这时候,如果不需要ContactList常驻内存,MainViewModel的OnNavigatedFrom的方法就长成这样了:

        public void OnNavigatedFrom(object obj)
{
base.Cleanup();
this.xxxxEvent -= xxxxHandler; foreach (var contact in ContactList)
{
contact.Cleanup();
}
ContactList.Clear();
}

  没有错哦,仍然是继承了ViewModelBase的ContactViewModel自己来释放内部的资源,但是Cleanup的调用是由外部引用ContactList的MainViewModel来发起的。

  本篇就ViewModelBase的继承使用展开了讨论,介绍了一点俺平时使用的经验,包括如何使用导航事件和释放资源。还希望能给萌新们启发,老司机们轻拍。

  另外MvvmLight框架使用入门系列可能会暂停一下(反正也没人看……),因为俺接下来要开始搞Win10的Universal App了,挖咔咔!

MvvmLight框架使用入门(四)的更多相关文章

  1. MvvmLight框架使用入门(三)

    本篇是MvvmLight框架使用入门的第三篇.从本篇开始,所有代码将通过Windows 10的Universal App来演示.我们将创建一个Universal App并应用MvvmLight框架. ...

  2. MvvmLight框架使用入门(5)

    上一次写MvvmLight框架使用入门(4)的时候还在用Visual Studio 2015,我儿子也不会过来盖上我的XPS……重启这个系列一方面是因为最近又开始写UWP的东西了,另一个是因为Mvvm ...

  3. MvvmLight框架使用入门(一)

    MvvmLight是比较流行的MVVM框架,相对较为简单易用.可能正因为简单,对应的帮助文档不多,对初学者就不够友好了.这里会用几篇随笔,就个人对MvvmLight的使用经验,来做一个入门的介绍. 第 ...

  4. MvvmLight框架使用入门(二)

    上一篇我们简单对MvvmLight做了介绍.罗列了三个DLL中,各个命名空间下主要类的定义及大致作用.因为只是范范的概论,对于从未接触过MvvmLight的萌新来说,根本就是在晃点他们.不过万事开头难 ...

  5. myBatis框架之入门(四)

    Mybatis多表管理查询 多表关联关系分析: 多表关联:至少两个表关联.分析多表关系的经验技巧:从一条记录出发,不要从表整体去分析,比如分析A表和B表关系,A表中的一条记录对应B表中的几条记录,如果 ...

  6. 实体框架 (EF) 入门 => 四、CodeFirst 枚举支持

    当使用 Code First 开发时,通常是从编写用来定义概念(域)模型的 .NET Framework 类开始. 插入记录没有为 Budget 赋值. 数值类型默认值为0,数据库中都为not nul ...

  7. Mybatis框架基础入门(四)--SqlMapConfig.xml配置文件简介

    SqlMapConfig.xml中配置的内容和顺序如下: properties(属性) settings(全局配置参数) typeAliases(类型别名) typeHandlers(类型处理器) o ...

  8. 【原创】NIO框架入门(四):Android与MINA2、Netty4的跨平台UDP双向通信实战

    概述 本文演示的是一个Android客户端程序,通过UDP协议与两个典型的NIO框架服务端,实现跨平台双向通信的完整Demo. 当前由于NIO框架的流行,使得开发大并发.高性能的互联网服务端成为可能. ...

  9. Veins(车载通信仿真框架)入门教程(四)——调试及记录结果

    Veins(车载通信仿真框架)入门教程(四)——调试及记录结果 在Veins入门教程(三)最后的动图中(如下图)可以看到大大小小的光圈,这个怎么实现的呢? 很简单,以收到RTS消息为例,通过finHo ...

随机推荐

  1. struct to point

    关键知识点:结构体--新数据类型定义及结构体变量的定义与初始化, 结构体指针变量的定义及相关应用. 结构体变量作函数参数 指向结构体变量的指针变量. 数组与结构体间的渊源始末, 当一个整体由多个数据构 ...

  2. 《OpenCL异构并行编程实战》补充笔记散点,第一至四章

    ▶ 总体印象:适合 OpenCL 入门的书,有丰富的代码和说明,例子较为简单.先把 OpenCL 代码的基本结构(平台 → 设备 → 上下文 → 命令队列 → 创建缓冲区 → 读写缓冲区 → 编译代码 ...

  3. Maven(三)理解Maven核心概念

    转载自: http://www.cnblogs.com/holbrook/archive/2012/12/24/2830519.html 本文以类图的方式,介绍maven核心的12个概念以及相互之间的 ...

  4. Git进阶--你可能不知道的很好用Git功能

    一.刚提交的代码,发现需要微调一下 刚刚最新提交了一段代码,然后跟前端说,接口好了.过了2分钟,前端跟你说,哎,兄弟,那个金额能不能返回整数,不要小数点. 这个时候一般我们通常会修改一下之后,再提交一 ...

  5. shell编程变量赋值

    [shell编程变量赋值] 1.等号两边均不能有空格存在.例, a="hello world"   2.变量和其它文字以{}或空格格开,否则会混淆.例, 有时候变量名可能会和其它文 ...

  6. oracle 知识点

    1.条件运算2.关联运算,子查询3.集合运算4.函数运算5.分组运算[group by](凑维度,条件,过滤,分组函数)6.行转列7.PL/SQL

  7. for 续5

    -------siwuxie095                 (五)usebackq 主要用于路径或文件名有空格时的情况 (说白了,就是对 in 后面的括号内集合进行转义)     单靠看帮助文 ...

  8. php通过反射执行某方法

    简单记录下通过反射来获取某方法的参数,然后利用php内置函数类执行此方法 一个简单的test类 class test { //2个参数默认值 public function b($name='lemo ...

  9. 电脑清缓存(C盘占空间)

    电脑缓存目录: 1.取消文件隐藏 2.找到C:\Users\lwx351192\AppData\Local\Temp目录下的三个子文件夹local,locallow,roaming里面的文件都可删除, ...

  10. 【记录】CentOS7安装NODEBB

    NodeBB介绍: NodeBB 是一个更好的论坛平台,专门为现代网络打造.它是免费的,易于使用. NodeBB 论坛软件是基于 Node.js开发,支持 Redis 或 MongoDB 的数据库.它 ...