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遇到的问题和解决方法的更多相关文章

  1. winform,wpf全屏 还显示任务栏的解决方法

    原文:winform,wpf全屏 还显示任务栏的解决方法 以wpf为例: 全屏代码: this.Topmost = true; this.WindowStyle = System.Windows.Wi ...

  2. WPF拖动DataGrid滚动条时内容混乱的解决方法

    WPF拖动DataGrid滚动条时内容混乱的解决方法 在WPF中,如果DataGrid里使用了模板列,当拖动滚动条时,往往会出现列表内容显示混乱的情况.解决方法就是在Binding的时候给Update ...

  3. MVVM框架下 WPF隐藏DataGrid一列

    最近的一个项目,需要在部分用户登录的时候,隐藏DataGrid中的一列,但是常规的绑定不好使,在下面举个例子. XAML部分代码 <Window x:Class="DataGridCo ...

  4. WPF ComboBox SelectionChanged事件里赋值Text的解决方法

    string sCountry ; private void cbCountry_SelectionChanged(object sender, SelectionChangedEventArgs e ...

  5. 简单的介绍下WPF中的MVVM框架

    最近在研究学习Swift,苹果希望它迅速取代复杂的Objective-C开发,引发了一大堆热潮去学它,放眼望去各个培训机构都已打着Swift开发0基础快速上手的招牌了.不过我觉得,等同于无C++基础上 ...

  6. ViewModel从未如此清爽 - 轻量级WPF MVVM框架Stylet

    Stylet是我最近发现的一个WPF MVVM框架, 在博客园上搜了一下, 相关的文章基本没有, 所以写了这个入门的文章推荐给大家. Stylet是受Caliburn Micro项目的启发, 所以借鉴 ...

  7. 浅谈WPF中的MVVM框架--MVVMFoundation

    先科普一下:什么是WPF,请看下图 微软对于WPF技术的构想是很宏大的,可惜普及率不高,不过如果你要做Windows客户端开发的话WPF技术还是值得一学的. 什么是MVVM模式 简单来说它是一种高级的 ...

  8. 基于WPF系统框架设计(6)-整合MVVM框架(Prism)

    应用场景 我们基础的框架已经搭建起来了,现在整合MVVM框架Prism,在ViewModel做一些逻辑处理,真正把界面设计分离出来. 这样方便我们系统开发分工合作,同时提高系统可维护性和灵活性. 具体 ...

  9. 在WPF的MVVM框架中获取下拉选择列表中的选中项

    文章概述: 本演示介绍怎样在WPF的MVVM框架中.通过数据绑定的方式获取下拉列表中的选中项.程序执行后的效果例如以下图所看到的: 相关下载(代码.屏幕录像):http://pan.baidu.com ...

随机推荐

  1. ASP.NET Core MVC/WebAPi 模型绑定探索

    前言 相信一直关注我的园友都知道,我写的博文都没有特别枯燥理论性的东西,主要是当每开启一门新的技术之旅时,刚开始就直接去看底层实现原理,第一会感觉索然无味,第二也不明白到底为何要这样做,所以只有当你用 ...

  2. 菜鸟学Struts2——Actions

    在对Struts2的工作原理学习之后,对Struts2的Action进行学习.主要对Struts2文档Guides中的Action分支进行学习,如下图: 1.Model Driven(模型驱动) St ...

  3. React使用antd Table生成层级多选组件

    一.需求 用户对不同的应用需要有不同的权限,用户一般和角色关联在一起,新建角色的时候会选择该角色对应的应用,然后对应用分配权限.于是写了一种实现的方式.首先应用是一个二级树,一级表示的是应用分组,二级 ...

  4. ASP.NET MVC开发日常一:SessionID合理清除

    在MVC Web开发中临时存储数据一般会用到Session,Cookie,ViewBag,ViewData,TempData.每个的使用场景是不同,具体区别有空再补上. Session数据最敏感,最需 ...

  5. MySQL 系列(四)主从复制、备份恢复方案生产环境实战

    第一篇:MySQL 系列(一) 生产标准线上环境安装配置案例及棘手问题解决 第二篇:MySQL 系列(二) 你不知道的数据库操作 第三篇:MySQL 系列(三)你不知道的 视图.触发器.存储过程.函数 ...

  6. Mysql基础代码(不断完善中)

    Mysql基础代码,不断完善中~ /* 启动MySQL */ net start mysql /* 连接与断开服务器 */ mysql -h 地址 -P 端口 -u 用户名 -p 密码 /* 跳过权限 ...

  7. jQuery可自动播放动画焦点图插件Koala

    Koala是一款简单而实用的jQuery焦点图幻灯片插件,焦点图不仅可以在播放图片的时候让图片有淡入淡出的动画效果,而且图片可以自动播放.该jQuery焦点图的每一张图片都可以设置文字描述,并浮动在图 ...

  8. VC中的MFC到底是什么?

    1. 微软基础类库(英语:Microsoft Foundation Classes,简称MFC)是一个微软公司提供的类库(class libraries),以C++类的形式封装了Windows API ...

  9. UGUI Text(Label)

    环境 Unity 5.3.6f1 关于Best Fit 如果勾选了 Best Fit ,当有大量的文本填充在Text上时,那么文字是不会自动换行的. 打字机效果 在github上已有现成的:https ...

  10. kvm上的Linux虚拟机使用virtio磁盘

    kvm上的Linux虚拟机使用virtio磁盘 系统:centos6.6  64位 网上的文章比较少,怎麽将Linux虚拟机的磁盘改为使用virtio磁盘 因为centos6或以上系统已经包含了vir ...