MVVM框架从WPF移植到UWP遇到的问题和解决方法
MVVM框架从WPF移植到UWP遇到的问题和解决方法
0x00 起因
这几天开始学习UWP了,之前有WPF经验,所以总体感觉还可以,看了一些基础概念和主题,写了几个测试程序,突然想起来了前一段时间在WPF下写的简易的MVVM框架(MVVM模式和在WPF中的实现),都是.NET平台的,移到通用类库里只要复制粘贴就可以了吧。抱着这个心态试了下,结果代码一片红,折腾了一下午总算搞得差不多了,第二天写了个测试试了下感觉基本问题应该是解决了。现在总结一下自己踩到的坑。
0x01 命令绑定
之前在WPF中实现ICommand接口时,将检查Command是否可以执行的_canExecute添加到CommandManager的RequerySuggested事件中(详细见MVVM模式解析和在WPF中的实现(三)命令绑定),这样在出现可能会影响命令执行状态的事件时,CommandManager会触发事件对命令的可执行状态进行检查,并将检查方法的返回值赋给命令绑定控件的IsEnable属性上。这样我们只要指定检查命令执行状态的方法即可,系统会自动检查。不过在UWP中这个CommandManager没有了,因此将无法再执行自动的命令可执行状态的检查。刚开始遇到这个问题时,按下Ctrl+.的组合键提示我引用WPF中的dll可以解决问题,按照提示操作了之后红色下划线果然没了,可是编译时提示我有冲突还是什么,后来去网上查如何解决这个冲突,自然没搞定。不过找到了MVVMLight的作者写的一篇文章http://blog.galasoft.ch/posts/2015/01/re-enabling-the-commandmanager-feature-with-relaycommand-in-mvvm-light-v5/,看来CommandManager是真没了。
为什么要在UWP中移除CommandManager呢,我也没找到答案,个人猜测应该是这个操作浪费了太多的资源吧,特别在手机终端资源(包括电量)是很有限的。这个事件在MSDN中的描述意思也很模糊

也就是说CommandManager认为某个行为会影响到命令执行状态就会触发事件执行检查。我在WPF中一直使用这个功能从未遇到过问题,由此可见能触发这个检查的事件或其它状态改变还是很多的,也就是说对命令执行状态的检查是很频繁的,而且当触发检查时会对所有注册了状态检查的命令检查一遍。可能检查100次才会有一次状态改变,也可能程序运行整个过程中状态检查结果都没有变化,所以这个冗余操作太多了。
那么在UWP中我们应该怎么检查命令的执行状态呢,刚开始我打算自己写个事件,绑定命令时把检查执行状态的方法订阅那个事件,然后设置个Timer来定时触发事件检查执行状态,这绝对是个馊主意,马上就否决了。后来考虑在ViewModel中的属性发生改变时进行检查,也是很多冗余操作,而且这种检查也很不完善。后来想想算了,干脆手动检查吧,这样检查的针对性强。具体做法就是在命令的类型中添加触发检查的方法RaiseCanExecuteChanged()方法。

0x02 事件绑定到命令
其实这个问题非常好解决的,结果我却踩到坑里一个多小时才爬出来。先说下事件绑定,再说下坑的事情。之前在WPF中将事件绑定到命令靠的是Interactivity.dll,在UWP中换了另外两个dll:Microsoft.Xaml.Interactivity.dll和Microsoft.Xaml.Interactions.dll,过方法类似。我的VS采用的是默认安装,这两个dll在C:\Program Files (x86)\Microsoft SDKs\Windows\v8.1\ExtensionSDKs\BehaviorsXamlSDKManaged\12.0\References\CommonConfiguration\Neutral这个位置。添加这两个dll的引用后就可以在XAML中实现事件绑定到命令了。下图代码绑定了主页面的PointerMoved事件至ViewModel中的CmdMouseMove命令。

特别值得一提的是之前在WPF中为了在事件绑定到命令后能够把时间的EventArgs传给命令,我们自己写了一个MyEventCommand类(MVVM设计模式和WPF中的实现(四)事件绑定),在UWP中就不需要了,InvokeCommandAction在不绑定CommandParameter的情况下默认就传递EventArgs参数,但当绑定了CommandParameter后传给Command的则为CommandParameter绑定的对象而不是事件的EventArgs参数。
这个应该是很简单的,结果我在测试的时候在类库的项目中引用了那两个dll,没有在测试项目中引入,所以在测试项目MainPage的XAML中进行引用命名空间时总是提示我不存在。记得以前刚换Windows8.1的时候遇到过类似问题,原因是系统会把来自网络的dll加锁,只要手动解锁就可以用了,翻了下之前那篇文章,也没在win10中看到有dll加锁啊。又开始怀疑dll版本不对,搜了好半天,最后发现是测试项目中没有引入那两个dll,反倒类库中没有必要引入。
0x03 其他一些问题
由于刚开始学习UWP开发,缺乏相关经验,因此在WPF中的View和ViewModel的通信和依赖注入不知道是不是适合于UWP,所以只是暂时把功能移过去,有待后面边学习边测试边修改。好吧,其实后面学习过程中写测试程序的话应该也不会用MVVM的。
另外移植过程中还发现从Type创建实例的方法变了,以前是这么写的:
type.Assembly.CreateInstance(type.FullName);
在UWP中需要这么写:
type.GetConstructor(Type.EmptyTypes).Invoke(parameters);
还有Dispatcher变成了CoreDispatcher等其他一些问题都与MVVM无关了,而且处理起来也都很容易,就不再讨论了。
0x04 示例
之前WPF版的MVVM框架还没来得及写示例,UWP版的反倒写了。示例很简单,界面如下图所示:

说明一下:
1.上边的TextBox显示的是当前鼠标相对于窗体的位置,随着鼠标移动显示数值会变化,方法是绑定了MainPage的PointerMoved事件,这说明了命令绑定运行正常,事件绑定命令并传递事件的参数也运行正常。
2.鼠标位置信息正确显示说明ViewModel中属性的数据绑定正常。
3.下面ListView数据正确显示说明绑定ViewModel中的集合属性正常。
4.按下Add会插入一条数据,按下Delete会删除选中数据,按下Clear会清空列表,说明命令绑定正常。
5.当无选中项时Delete按钮禁用,说明命令执行状态检查正常。
0x05 相关下载
https://github.com/durow/AyxMVVM
更多内容欢迎访问我的博客:http://www.durow.vip
MVVM框架从WPF移植到UWP遇到的问题和解决方法的更多相关文章
- winform,wpf全屏 还显示任务栏的解决方法
原文:winform,wpf全屏 还显示任务栏的解决方法 以wpf为例: 全屏代码: this.Topmost = true; this.WindowStyle = System.Windows.Wi ...
- WPF拖动DataGrid滚动条时内容混乱的解决方法
WPF拖动DataGrid滚动条时内容混乱的解决方法 在WPF中,如果DataGrid里使用了模板列,当拖动滚动条时,往往会出现列表内容显示混乱的情况.解决方法就是在Binding的时候给Update ...
- MVVM框架下 WPF隐藏DataGrid一列
最近的一个项目,需要在部分用户登录的时候,隐藏DataGrid中的一列,但是常规的绑定不好使,在下面举个例子. XAML部分代码 <Window x:Class="DataGridCo ...
- WPF ComboBox SelectionChanged事件里赋值Text的解决方法
string sCountry ; private void cbCountry_SelectionChanged(object sender, SelectionChangedEventArgs e ...
- 简单的介绍下WPF中的MVVM框架
最近在研究学习Swift,苹果希望它迅速取代复杂的Objective-C开发,引发了一大堆热潮去学它,放眼望去各个培训机构都已打着Swift开发0基础快速上手的招牌了.不过我觉得,等同于无C++基础上 ...
- ViewModel从未如此清爽 - 轻量级WPF MVVM框架Stylet
Stylet是我最近发现的一个WPF MVVM框架, 在博客园上搜了一下, 相关的文章基本没有, 所以写了这个入门的文章推荐给大家. Stylet是受Caliburn Micro项目的启发, 所以借鉴 ...
- 浅谈WPF中的MVVM框架--MVVMFoundation
先科普一下:什么是WPF,请看下图 微软对于WPF技术的构想是很宏大的,可惜普及率不高,不过如果你要做Windows客户端开发的话WPF技术还是值得一学的. 什么是MVVM模式 简单来说它是一种高级的 ...
- 基于WPF系统框架设计(6)-整合MVVM框架(Prism)
应用场景 我们基础的框架已经搭建起来了,现在整合MVVM框架Prism,在ViewModel做一些逻辑处理,真正把界面设计分离出来. 这样方便我们系统开发分工合作,同时提高系统可维护性和灵活性. 具体 ...
- 在WPF的MVVM框架中获取下拉选择列表中的选中项
文章概述: 本演示介绍怎样在WPF的MVVM框架中.通过数据绑定的方式获取下拉列表中的选中项.程序执行后的效果例如以下图所看到的: 相关下载(代码.屏幕录像):http://pan.baidu.com ...
随机推荐
- Python高手之路【五】python基础之正则表达式
下图列出了Python支持的正则表达式元字符和语法: 字符点:匹配任意一个字符 import re st = 'python' result = re.findall('p.t',st) print( ...
- 【WCF】错误协定声明
在上一篇烂文中,老周给大伙伴们介绍了 IErrorHandler 接口的使用,今天,老周补充一个错误处理的知识点——错误协定. 错误协定与IErrorHandler接口不同,大伙伴们应该记得,上回我们 ...
- react-redux
1. 首先redux,与react是两个独立的个体,项目中可以只用react,也可以只用redux 1.1 react-redux: 是一个redux作者专门为react制作的 redux, 增加了新 ...
- 和 Thrift 的一场美丽邂逅
一. 与 Thrift 的初识 也许大多数人接触 Thrift 是从序列化开始的.每次搜索 “java序列化” + “方式”.“对比” 或 “性能” 等关键字时,搜索引擎总是会返回一大堆有关各种序列化 ...
- Node.js:进程、子进程与cluster多核处理模块
1.process对象 process对象就是处理与进程相关信息的全局对象,不需要require引用,且是EventEmitter的实例. 获取进程信息 process对象提供了很多的API来获取当前 ...
- 如何安全的将VMware vCenter Server使用的SQL Server Express数据库平滑升级到完整版
背景: 由于建设初期使用的vSphere vCenter for Windows版,其中安装自动化过程中会使用SQL Server Express的免费版数据库进行基础环境构建.而此时随着业务量的增加 ...
- python 数据类型 ---文件一
1.文件的操作流程: 打开(open), 操作(read,write), 关闭(close) 下面分别用三种方式打开文件,r,w,a 模式 . "a"模式将不会覆盖原来的文件内容, ...
- Block解析(iOS)
1. 操作系统中的栈和堆 我们先来看看一个由C/C++/OBJC编译的程序占用内存分布的结构: 栈区(stack):由系统自动分配,一般存放函数参数值.局部变量的值等.由编译器自动创建与释放.其操作方 ...
- Linux环境下常见漏洞利用技术(培训ppt+实例+exp)
记得以前在drops写过一篇文章叫 linux常见漏洞利用技术实践 ,现在还可以找得到(https://woo.49.gs/static/drops/binary-6521.html), 不过当时开始 ...
- Unit Of Work的设计
在DDD开发过程中,一个良好的Uow设计必不可少,我心目中的Uow设计应该具备以下几点: 1.有着良好的抽象,有着恰如其分的命名: 2.能够应付不同的组件,比如你的系统中可能会存在EfUnitOfWo ...