博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MvvmLight框架使用入门(四)
阅读量:4594 次
发布时间:2019-06-09

本文共 4231 字,大约阅读时间需要 14 分钟。

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

ICleanup

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

ObservableObject

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

ViewModelBase

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

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

  我们先看一下最基本的SetRaisePropertyChanged方法的使用:

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

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

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

  ViewModelBase里的Cleanup方法:

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

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

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里的NavigatedFromNavigatedTo方法,传递参数,把处理的逻辑放到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
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();        }

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

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

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

 

 

 

 

转载于:https://www.cnblogs.com/manupstairs/p/4948347.html

你可能感兴趣的文章
接口测试基础篇
查看>>
LeetCode 102. 二叉树的层次遍历
查看>>
CCF | 小中大
查看>>
LeetCode 589. N叉树的前序遍历
查看>>
LeetCode 145. 二叉树的后序遍历
查看>>
Java | JDK8下的ConcurrentHashMap#putValue
查看>>
LeetCode 144. 二叉树的前序遍历
查看>>
周总结
查看>>
作业13-网络java
查看>>
Qt加载lib文件
查看>>
element vuex 语音播报
查看>>
tomcat剖析(二)
查看>>
装机摸鱼日志--ubuntu16.04安装网易云音乐客户端
查看>>
eclipse中Android模拟器,DDMS看不到设备
查看>>
Flex 布局教程学习
查看>>
day11_rowid、rownum、表分类
查看>>
软件测试培训第4天
查看>>
Android:网络操作2.3等低版本正常,4.0(ICS)以上出错,换用AsyncTask异步线程get json...
查看>>
单次插入与批量插入时间对比
查看>>
python从excel读取的数据为数字时,自动加上.0转化为浮点型的解决
查看>>