介绍

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-数据绑定和命令的更多相关文章

  1. Prism 源码解读1-Bootstrapper和Region的创建

    介绍 之前也研究过Prism框架但是一直没有深入理解,现在项目上想把一个Winform的桌面应用程序改造成WPF程序,同时我希望程序是可测试可维护架构良好的,Prism的这些设计理念正好符合我的需求, ...

  2. Prism 源码解读2-View的加载和控制

    介绍 上一篇介绍了Region,这一篇跟Region息息相关,讲一下Region中View的加载方式及控制. 4.ViewDiscovery 在创建好Region后需要将View添加到Region中. ...

  3. Prism 源码解读3-Modules加载

    介绍 在软件开发过程中,总想组件式的开发方式,各个组件之间最好互不影响,独立测试.Prism的Modules很好的满足了这一点. 这个架构图很好了讲解了Prism的Modules的概念 Prism支持 ...

  4. Prism 源码解读4-ViewModel注入

    介绍 介绍一个Prism的MVVM实现,主要介绍Prism如何在WPF上进行的一些封装,以实现MVVM.MVVM到底是什么呢?看一下这一幅经典的图 以前没有ViewModel这个概念,就是将Model ...

  5. Prism 源码解读6-事件聚合

    0 介绍 事件提供的是1对多的绑定,通过委托链实现对订阅者的调用,事件必须要通过发布者调用.同时事件订阅是强引用,事件订阅者的生命周期总是大于等于事件发布者.如果代码中事件很多就会充斥着各种事件的订阅 ...

  6. Prism 源码解读7-导航

    介绍 Prism提供了一个非常强大的功能导航,导航的意思就是指定对应的View显示.这个导航的强大之处有: 可以设置导航前后的动作 可以指定View实例的生命周期,可以是否导航到新的View实例 提供 ...

  7. Laravel 源码解读系列第四篇-Auth 机制

    前言 Laravel有一个神器: php artisan make:auth 能够快速的帮我们完成一套注册和登录的认证机制,但是这套机制具体的是怎么跑起来的呢?我们不妨来一起看看他的源码.不过在这篇文 ...

  8. php-msf 源码解读【转】

    php-msf: https://github.com/pinguo/php-msf 百度脑图 - php-msf 源码解读: http://naotu.baidu.com/file/cc7b5a49 ...

  9. create-react-app源码解读之为什么不搞个山寨版的create-react-app呢?

    最近把 vue-cli@2.x 和 create-react-app 的源码都看了一遍.由于现在官方推荐使用 vue-cli@3.0 ,改动比较大,所以就不写关于 vue-cli 的了(据说是因为 v ...

随机推荐

  1. C语言程序设计100例之(31):全排列问题

    例31   全排列问题 题目描述 输出自然数1到n所有不重复的排列,即n的全排列,要求所产生的任一数字序列中不允许出现重复的数字. 输入格式 n(1≤n≤9) 输出格式 由1-n组成的所有不重复的数字 ...

  2. 复习笔记——1. C语言基础知识回顾

    1. 数据类型 1.1 基本数据类型 整型:int, long,unsigned int,unsigned long,long long-- 字符型:char 浮点型:float, double-- ...

  3. iview 踩坑之旅

    公司重构管理系统,框架定了vue,UI在element和iview之间选,element样式被吐槽丑,于是选了iview,但是,,这个坑多啊... 废话少说,罗列了iview中容易出错或者懵逼的一些地 ...

  4. springmvc与swagger2

    首先呢我们导入相关的jar包文件 为了方便copy我copy一份 <!-- 导入java ee jar 包 -->        <dependency>           ...

  5. windows7免费永久激活方法分享

    前言 我相信,这里肯定有看过我上一篇博客的同学. 我说了,为解决windows7激活问题,我会找一个比较好的方法. 首先先让大家看一看激活前windows7的计算机属性: 显示是未激活的.下面就是方法 ...

  6. CVPR 2020 三篇有趣的论文解读

    作者 | 文永亮 学校 | 哈尔滨工业大学(深圳) 研究方向 | 视频预测.时空序列预测 目录 AdderNet - 其实不需要这么多乘法 Deep Snake for Real-Time Insta ...

  7. Ubuntu部署Asp.net core网站无法访问

    前几天应工作需要,在阿里云上部署一个测试站点.本以为分分钟的事情,没想到打脸了. 当时直接新建一个webapi项目,publish后直接上传到阿里云,随后设置nginx转发网站端口5000. 接着打开 ...

  8. vue-cli实现最简单的全选、全不选、反选功能。不容错过呦!!!!!话不多说直接上代码。。。。

    <template> <div class="hello"> <input type="button" name="al ...

  9. MATLAB神经网络(1)之R练习

    )之R练习 将在MATLAB神经网络中学到的知识用R进行适当地重构,再写一遍,一方面可以加深理解和记忆,另一方面练习R,比较R和MATLAB的不同.如要在R中使用之前的数据,应首先在MATLAB中用w ...

  10. Simulink仿真入门到精通(四) Simulink子系统

    4.1 Simulink子系统详解 4.1.1 子系统概述 Simulink根据仿真特性将模块的属性分为两种:虚拟模块和非虚拟模块. 非虚拟模块在仿真过程中起到实际的作用,对其进行编辑或者增加删除操作 ...