Prism 源码解读5-数据绑定和命令
介绍
WPF本身就支持通知、绑定和命令,实现ViewModel和VIew之间的通讯,但相对来说功能比较少,Prism扩充了这些功能并提供更加强有力,简洁的数据绑定和命令。
0 绑定通知
WPF的绑定通知需要实现INotifyPropertyChanged接口,也就是实现一个属性改变事件,用来通知UI属性改变了,让UI更新。该事件需要一个事件参数new PropertyChangedEventArgs(propertyName)传入属性的名字,这样的调用方式比较繁琐。
Prism扩充了WPF的绑定通知。提供了BindableBase 实现了 INotifyPropertyChanged接口,并使用CallerMemberName获取属性名字。这样就解决了属性改变事件调用繁琐的问题。同时在内部还是对相等值进行了过滤。


简单愉快的调用吧

只需要使用SetProperty方法就可以自动更新UI了。
值得注意的是OnPropertyChanged还提供了对Expression的支持

也就是主动调用OnPropertyChanged(()=>this.PropertyName),也可以触发UI响应。
1 命令
DelegateCommand
WPF命令和通知有点类似,命令需要实现ICommand接口,实现Execute方法,命令状态CanExecute和命令状态改变事件。并且WPF只实现了一个RoutedCommand。Prism提供了一个DelegateCommandBase命令基类实现ICommand,并扩充了子类DelegateCommand,大大简化了命令调用方式


看到在基类中有_synchronizationContext线程同步上下文,用来保证命令执行的时候线程同步。
重点关注一下子类中的几个方法



1.ExecuteDelegateCommand = new DelegateCommand(Execute, CanExecute);
- 这个命令声明方式,如果命令状态发生变化的时候需要主动调用RaiseCanExecuteChanged方法来触发命令状态改变事件。
2.DelegateCommandObservesProperty = new DelegateCommand(Execute, CanExecute).ObservesProperty(() => IsEnabled);
- 可以看到这种声明方式,提供了一个ObservesProperty方法,不需要显示调用命令状态改变事件。
3.DelegateCommandObservesCanExecute = new DelegateCommand(Execute).ObservesCanExecute(() => IsEnabled);
- 这种声明方法提供ObservesCanExecute方法,直接观测命令状态改变事件和属性。
4.ExecuteGenericDelegateCommand = new DelegateCommand(ExecuteGeneric).ObservesCanExecute(() => IsEnabled);
- 这是一个使用泛型带参数的声明方式,
看一下内部怎么实现这种简单而强大的功能


通过Expression,内部调用PropertyObserver.Observes()方法并将RaiseCanExecuteChaned方法传入。
在PropertyObserver将Expression保存在一个链表,并每个节点都订阅OnPropertyChanged事件。

CompositeCommand
Prism还提供了一个CompositeCommand命令

这个命令的功能跟其名字一样,就是复合命令,命令集合。
- 将DelegateCommand实例放到其中,每当调用CompositeCommand调用的时候会调用它保存的所有命令,
- 命令集合中任何一个命令状态改变,都会触发CompositeCommand命令状态的改变事件,导致CompositeCommand检查集合中所有的命令状态,首先会检查IActiveAware,再检查命令状态,如果任何一个命令状态是False,都会导致组合命令返回False
来看一下源码



注意到,聚合命令也是通过线程上下文保持线程同步,同时看到有检测IActiveAware接口,这个接口是什么意思呢?其实就是查看该命令是否激活。这个接口有一个激活状态属性和一个激活状态改变事件,

只要界面主动调用UpdateCommand.IsActive = true;命令就会被激活并触发复合命令的激活状态改变回调函数


在复合命令的ShouldExcute方法中检查其激活状态,命令集合中没有激活命令,那么复合命令的执行状态也会改变。
命令执行和激活状态都是差不多的接口,有状态和状态改变事件组成,感觉很多地方都有相似的模式,有点像订阅模式,也有点像状态机,包括一些Collection和Storage.
总结
主要讲了下Prism提供的绑定通知和命令,学习到如何在WPF框架基础上做一些封装,如果可能甚至可以自己重新封装一些功能更强大的命令来兼容Prism。
Prism 源码解读5-数据绑定和命令的更多相关文章
- Prism 源码解读1-Bootstrapper和Region的创建
介绍 之前也研究过Prism框架但是一直没有深入理解,现在项目上想把一个Winform的桌面应用程序改造成WPF程序,同时我希望程序是可测试可维护架构良好的,Prism的这些设计理念正好符合我的需求, ...
- Prism 源码解读2-View的加载和控制
介绍 上一篇介绍了Region,这一篇跟Region息息相关,讲一下Region中View的加载方式及控制. 4.ViewDiscovery 在创建好Region后需要将View添加到Region中. ...
- Prism 源码解读3-Modules加载
介绍 在软件开发过程中,总想组件式的开发方式,各个组件之间最好互不影响,独立测试.Prism的Modules很好的满足了这一点. 这个架构图很好了讲解了Prism的Modules的概念 Prism支持 ...
- Prism 源码解读4-ViewModel注入
介绍 介绍一个Prism的MVVM实现,主要介绍Prism如何在WPF上进行的一些封装,以实现MVVM.MVVM到底是什么呢?看一下这一幅经典的图 以前没有ViewModel这个概念,就是将Model ...
- Prism 源码解读6-事件聚合
0 介绍 事件提供的是1对多的绑定,通过委托链实现对订阅者的调用,事件必须要通过发布者调用.同时事件订阅是强引用,事件订阅者的生命周期总是大于等于事件发布者.如果代码中事件很多就会充斥着各种事件的订阅 ...
- Prism 源码解读7-导航
介绍 Prism提供了一个非常强大的功能导航,导航的意思就是指定对应的View显示.这个导航的强大之处有: 可以设置导航前后的动作 可以指定View实例的生命周期,可以是否导航到新的View实例 提供 ...
- Laravel 源码解读系列第四篇-Auth 机制
前言 Laravel有一个神器: php artisan make:auth 能够快速的帮我们完成一套注册和登录的认证机制,但是这套机制具体的是怎么跑起来的呢?我们不妨来一起看看他的源码.不过在这篇文 ...
- php-msf 源码解读【转】
php-msf: https://github.com/pinguo/php-msf 百度脑图 - php-msf 源码解读: http://naotu.baidu.com/file/cc7b5a49 ...
- create-react-app源码解读之为什么不搞个山寨版的create-react-app呢?
最近把 vue-cli@2.x 和 create-react-app 的源码都看了一遍.由于现在官方推荐使用 vue-cli@3.0 ,改动比较大,所以就不写关于 vue-cli 的了(据说是因为 v ...
随机推荐
- 一步到位datatabls中文化
#一步到位datatabls中文化 加入以下代码 $(document).ready(function () { $('#declarationList').DataTable({ destroy:t ...
- k8s环境部署.net core web项目(docker本地仓库)
在之前的文档中,我们部署了.net core web在k8s环境下,达成了集群管理项目的目的.但是,由于是本地部署,需要在所有的node节点都拉取好镜像,这是非常麻烦的,为了只维护一份代码,同步更新. ...
- python2.7.6安装easy_install (windows 64 环境)
1.复制以下代码保存到easy_install.py文件中(文件名可随意命名)并将该文件放到python的安装路径中(如:D:\Python27) #!/usr/bin/env python &quo ...
- YAML语法使用,JSR303数据校验
YAML YAML是 "YAML Ain't a Markup Language" (YAML不是一种置标语言)的递归缩写 # yaml配置 server: prot: YAML语 ...
- 沃土前端系列 - HTML常用标签
html是什么 HTML是Hyper Text Markup Language的缩写,中文的意思是"超文本标记语言",它是制作网页的标准语言.由于网页中不仅包含普通文本,还包含超文 ...
- 聊聊CAS - 面试官最喜欢问的并发编程专题
什么是CAS 学习Java并发编程,CAS(Compare And Set)机制都是一个不得不掌握的知识点.除了通过synchronized进行并发控制外,还可以通过CAS的方式控制,大家熟悉的Ree ...
- pikachu——暴力破解
前述: 前面学习了sqli-labs 和 DVWA,也算是初步涉足了web漏洞,了解了一些web漏洞的知识.所以在pikachu上面,会更加仔细认真,把前面没有介绍到的知识点和我一边学习到的新知识再补 ...
- 【tomcat系列】详解tomcat架构(上篇)
java中,常用的web服务器一般由tomcat,weblogic,jetty,undertwo等,但从用户使用广泛度来说,tomcat用户量相对比较大一些,当然这也基于它开源和免费的特点. 从软件架 ...
- (转)协议森林08 不放弃 (TCP协议与流通信)
协议森林08 不放弃 (TCP协议与流通信) 作者:Vamei 出处:http://www.cnblogs.com/vamei 欢迎转载,也请保留这段声明.谢谢! TCP(Transportation ...
- layui的弹出层的title的自定义html
layui的弹出层的title的自定义html //在这里面输入任何合法的js语句 layer.open({ type: 1 //Page层类型 ,area: ['500px', '300px' ...