MVVM模式解析和在WPF中的实现(六)

用依赖注入的方式配置ViewModel并注册消息

系列目录:

MVVM模式解析和在WPF中的实现(一)MVVM模式简介

MVVM模式解析和在WPF中的实现(二)数据绑定

MVVM模式解析和在WPF中的实现(三)命令绑定

MVVM模式解析和在WPF中的实现(四)事件绑定

MVVM模式解析和在WPF中的实现(五)View和ViewModel的通信

MVVM模式解析和在WPF中的实现(六)用依赖注入的方式配置ViewModel并注册消息

0x00 最初的想法

这次主要讨论下给View指定ViewModel的事情。一般来说给View指定ViewModel常用的方式有两种,一种是在View的后台代码中写DataContext = new ViewModel(),还有一种是在XAML中指定View的DataContext。这两种方式都使得View对ViewModel产生了依赖,这种情况下可以考虑用依赖注入的方式使取消View对ViewModel的直接依赖。依赖注入一般来说可以通过构造函数注入、通过设置属性注入,这两种方法对于View来说都不合适。因此可以使用IoC Container,让View主动去获取对应的ViewModel。

其实给View指定一个ViewModel并不属于频繁的操作,而且改起来也很容易,费半天劲搞个依赖注入确实不太至于。就像上篇文章中废了半天劲搞了个View和ViewModel的通信一样,用到的概率比较小,而且也有别的方式解决,虽然那种方式并不符合MVVM模式。不过View除了依赖ViewModel之外对消息注册器也是会产生依赖的,而且某种类型的View一般来说都依赖固定类型的ViewModel和消息注册器,因此可以一次注入两个依赖,这样貌似就值了,至少我认为是值了,所以有了ViewModelManager这个类。

0x01 ViewModel和MessageManager的依赖注入

使用静态类ViewModelManager来当作IoC Container。往IoC Container里注册依赖关系一般有两种方式,一种是将依赖关系以某种形式(例如xml)保存在外部,一种是在程序中注册到一个列表里。我采取第二种做法,因为比较容易:)

程序在启动时使用ViewModelManager.Register将依赖关系注册到ViewModelManager中,View在构造函数中调用ViewModelManager.SetViewModel(this);来设置View的DataContext并通过依赖的消息注册器注册消息,消息注册器可以为空,代表View不接收消息。它们的关系如图所示:

需要说明的有两个地方:

一个是View和ViewModel的对应关系。一般来说一个View对应着一种ViewModel,这样注册起来是没问题的。但这个并不绝对,理论上来说一个View可以将DataContext设置为任意ViewModel,如果一个View可以设置多种ViewModel该如何处理呢,这时候可以在ViewModelManager注册时添加Token属性,然后用SetViewModel(this,token)的方式指定特定的ViewModel为DataContext。

另一个是消息注册的范围。因为一般来说ViewModel都是和绑定的View通信。所以默认情况下,消息注册到单独一个MessageManager中,这个MessageManager保存ViewModel中,ViewModel使用这个MessageManager发送消息,发送的消息由View接收。但如果需要和其他View通信,需要把消息注册到MessageManager.Default中,这个对象是static的,要达到这个目的只要在View设置ViewMode时这样来SetViewModel(this,isGlobalMsg:true)即可。如果ViewModel又想和绑定的View单独通信,有时候还需要和别的View通信,可以在消息注册器中注册时将需要单独通信的消息设置一个Group,ViewModel在发送消息时加一个Group过滤一下即可。一个Group可以理解为消息的单独一个通道。

顺带一提,好吧只是顺带一提的是,在给View注入ViewModel时,顺便把ViewModel的UIDispatcher属性设置为了View的Dispatcher,虽然我不知道这有什么用。但这样在ViewModel中使用UIDispatcher时即为相关的View的Dispatcher。如果要使用MainWindow的Dispatcher可以通过DispatcherHelper.Dispatcher或者App.Current.MainWindow.Dispatcher获得。

0x02 写在最后

到此为止我能想到的MVVM框架的功能算是基本实现了,遇到的需求十分有限,才能也十分有限,能想到的就这几个了,欢迎回复讨论,也欢迎加我QQ16141860交流。之前一直是在TestArea这个仓库里进行测试,现在这个小框架整理了下,放到AyxMVVM仓库里了。现在有些想法还不太成熟,使用过程中遇到问题也会随时修正,以后就都修改到AyxMVVM中了,TestArea中的MyMVVM不再维护了。另外给仓库起名真是件麻烦事,干脆统一都用Ayx+XXX的方式,这样既容易重复的概率又十分小。Ayx是我名字拼音的首字母,想想看以拼音A开头的姓氏之少就能想到几乎不会出现重复了。最后,10月6日看了微软的秋季产品发布会后信仰充值成功。对UWP十分感兴趣,下一步打算学习一下。

0x03 关于AyxMVVM

https://github.com/durow/AyxMVVM

MVVM模式解析和在WPF中的实现(六) 用依赖注入的方式配置ViewModel并注册消息的更多相关文章

  1. MVVM模式用依赖注入的方式配置ViewModel并注册消息

    最初的想法 这次主要讨论下给View指定ViewModel的事情.一般来说给View指定ViewModel常用的方式有两种,一种是在View的后台代码中写DataContext = new ViewM ...

  2. MVVM模式解析和在WPF中的实现(五)View和ViewModel的通信

    MVVM模式解析和在WPF中的实现(五) View和ViewModel的通信 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 M ...

  3. MVVM模式解析和在WPF中的实现(三)命令绑定

    MVVM模式解析和在WPF中的实现(三) 命令绑定 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在WPF中 ...

  4. 在WPF中使用依赖注入的方式创建视图

    在WPF中使用依赖注入的方式创建视图 0x00 问题的产生 互联网时代桌面开发真是越来越少了,很多应用都转到了浏览器端和移动智能终端,相应的软件开发上的新技术应用到桌面开发的文章也很少.我之前主要做W ...

  5. WPF中使用文件浏览对话框的几种方式

    原文:WPF中使用文件浏览对话框的几种方式 WPF本身并没有为我们提供文件浏览的控件, 也不能直接使用Forms中的控件,而文件浏览对话框又是我们最常用的控件之一. 下面是我实现的方式 方式1: 使用 ...

  6. 示例:WPF中自定义MessageService应用DialogHost、Snackbar、NotifyIcon显示各种场景提示消息

    原文:示例:WPF中自定义MessageService应用DialogHost.Snackbar.NotifyIcon显示各种场景提示消息 一.目的:不同交互场景需要提示不同的消息,不同的消息需要用不 ...

  7. ASP.NET Core中的依赖注入(3): 服务的注册与提供

    在采用了依赖注入的应用中,我们总是直接利用DI容器直接获取所需的服务实例,换句话说,DI容器起到了一个服务提供者的角色,它能够根据我们提供的服务描述信息提供一个可用的服务对象.ASP.NET Core ...

  8. 轻松了解Spring中的控制反转和依赖注入(二)

    紧接上一篇文章<轻松了解Spring中的控制反转和依赖注入>讲解了SpringIOC和DI的基本概念,这篇文章我们模拟一下SpringIOC的工作机制,使我们更加深刻的理解其中的工作. 类 ...

  9. Spring学习(三)——Spring中的依赖注入的方式

    [前面的话] Spring对我太重要了,做个关于web相关的项目都要使用Spring,每次去看Spring相关的知识,总是感觉一知半解,没有很好的系统去学习一下,现在抽点时间学习一下Spring.不知 ...

随机推荐

  1. virtualbox linux虚拟机相关

    linux虚拟机设置为静态IP 在virtualbox中安装好linux虚拟机后,如果采用的是NAT方式的话,linux虚拟机默认采用dhcp方式自动上网,而且用的是NetworkManager服务而 ...

  2. 【走过巨坑】android studio对于jni调用及运行闪退无法加载库的问题解决方案

    相信很多小伙伴都在android开发中遇到调用jni的各种巨坑,因为我们不得不在很多地方用到第三方库so文件,然而第三方官方通常都只会给出ADT环境下的集成方式,而谷歌亲儿子android studi ...

  3. 创建ABPboilerplate模版项目

    本文是根据角落的白板报的<通过ABPboilerplate模版创建项目>一文的学习总结,感谢原文作者角落的白板报. 1 准备 开发环境: Visual Studio 2015 update ...

  4. nginx服务器安装及配置文件详解

    nginx在工作中已经有好几个环境在使用了,每次都是重新去网上扒博客,各种编译配置,今天自己也整理一份安装文档和nginx.conf配置选项的说明,留作以后参考.像负载均衡配置(包括健康检查).缓存( ...

  5. 原生JS实现-星级评分系统

    今天我又写了个很酷的实例:星级评分系统(可自定义星星个数.显示信息) sufuStar.star();使用默认值5个星星,默认信息 var msg = [........]; sufuStar.sta ...

  6. 解决使用IE8打开ADFS 3.0登录页面

    系统上线前一天,发现客户竟然有XP系统和2003系统,这些系统都不能访问外网.测试时,客户端是IE8,打开我们系统ADFS的登录页面,一直在Loading,无法打开,也不报错.后来通过fiddler跟 ...

  7. Xamarin中使用DatePickerDialog的相关问题

    在Xamarin中在使用Datepicker的时候,一般情况下只需要在对应的按钮或其他控件的点击事件中使用如下语句即可完成: EditText etBirthday = FindViewById< ...

  8. 【腾讯Bugly干货分享】WebVR如此近-three.js的WebVR示例解析

    本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57c7ff1689a6c9121b1adb16 作者:苏晏烨 关于WebVR 最 ...

  9. Spring7:基于注解的Spring MVC(下篇)

    Model 上一篇文章<Spring6:基于注解的Spring MVC(上篇)>,讲了Spring MVC环境搭建.@RequestMapping以及参数绑定,这是Spring MVC中最 ...

  10. Windows10自适应和交互式toast通知[1]

    阅读目录: 概述 toast通知的结构 视觉区域(Visual) 行为(Actions) 特定场景下的Toast通知 带多内容的通知 带行为的通知(例子1) 带行为的通知(例子2) 带文本输入框和行为 ...