在开发大型复杂系统时,我们通常会按功能将系统分成很多模块,这样模块就可以独立的并行开发、测试、部署、修改。使用Prism框架设计表现层时,我们也会遵循这个原则,按功能相关性将界面划分为多个模块,每个模块又包含多个Region。这就需要解决模块之间、Region之间经常需要进行通信的问题,Prism提供了以下几种方式:

1、聚合事件(Event aggregation

使用方式,先在一个公共模块中定义一个事件MyEvent ,传输数据为MyEntity。

public class MyEvent : CompositePresentationEvent<MyEntity>
{
}

然后在需要等待处理事件的模块中订阅事件,如下所示:

private IEventAggregator eventAggregator;

eventAggregator = (IEventAggregator)ServiceLocator.Current.GetService(typeof(IEventAggregator));

eventAggregator.GetEvent<MyEvent>().Subscribe(MyEventHandler, true);

public void MyEventHandler(MyEntity myEntity)
{

}

eventAggregator 相当于一个全局的集合,保存了所有订阅的事件。

在发起通信的模块中发布事件,如下所示:

eventAggregator.GetEvent<CreatePlanEvent>().Publish(new MyEntity());

2、全局命令

使用方式,在公共模块中定义一个全局命令类:

public static class GlobalCommands
{
        public static CompositeCommand OpenCommand = new CompositeCommand();

}

在使用该命令的View中:

<Button Command="{x:Static s:GlobalCommands.OpenCommand }" >

在响应该命令的模块中:

public ICommand OpenCommand { get; set; }

OpenCommand = new RelayCommand(param => this.Open(param));

GlobalCommands.OpenCommand.RegisterCommand(OpenCommand);

不用绑定时可以这样执行:

GlobalCommands.OpenCommand.Execute(param);

3、Region context

在Prism安装文件中自带的UIComposition例子中演示了两个Tab页共享一个数据集,

用法是在View中:

prism:RegionManager.RegionContext="{Binding CurrentEmployee}"

在两个Tab页的View的后台代码中:

RegionContext.GetObservableContext(this).PropertyChanged += (s, e)
                                                                        =>
                                                                        employeeDetailsViewModel.CurrentEmployee =
                                                                        RegionContext.GetObservableContext(this).Value
                                                                        as Employee;

我们还可以利用Region.Context属性共享数据,Region.Context中可以保存任何该Region需要与其他Region共享的数据。

因此我在实际使用时用Region.Context来保存一个控件对象的引用。如下所示:

在一个模块中保存

mainRegion.Context = new ContentControl();

在另一个模块中取出

IRegion mainRegion = regionManager.Regions["MainRegion"];
if (mainRegion == null) return;
ContentControlpane = mainRegion.Context as ContentControl;

因为regionManager是全局的,所以可以随时获得感兴趣的Region和Context

4、共享服务

这种方法我们在前面已经接触到了,如:

eventAggregator = (IEventAggregator)ServiceLocator.Current.GetService(typeof(IEventAggregator));

还可以,container= (IEventAggregator)ServiceLocator.Current.GetService(typeof(IUnityContainer));

IEventAggregator和IUnityContainer是Prism已有的服务,我们还可以自定义服务,请参考Prism自带的StockTrader RI例子

中的IMarketHistoryService服务。

Prism学习笔记-模块之间通信的几种方式的更多相关文章

  1. IPC进程之间通信的几种方式

    概念 进程间通信就是在不同进程之间传播或交换信息,那么不同进程之间存在着什么双方都可以访问的介质呢?进程的用户空间是互相独立的,一般而言是不能互相访问的,唯一的例外是 共享内存区 .但是,系统空间却是 ...

  2. Android Service与Activity之间通信的几种方式

    在Android中,Activity主要负责前台页面的展示,Service主要负责需要长期运行的任务,所以在我们实际开发中,就会常常遇到Activity与Service之间的通信,我们一般在Activ ...

  3. Vue组件之间通信的三种方式

    最近在看梁颠编著的<Vue.js实战>一书,感觉颇有收获,特此记录一些比价实用的技巧. 组件是MVVM框架的核心设计思想,将各功能点组件化更利于我们在项目中复用,这类似于我们服务端面向对象 ...

  4. vue组件之间通信的8种方式

    对于vue来说,组件之间的消息传递是非常重要的,下面是我对组件之间消息传递的常用方式的总结. props和$emit(常用) $attrs和$listeners 中央事件总线(非父子组件间通信) v- ...

  5. Liferay7 BPM门户开发之33: Portlet之间通信的3种方式(session、IPC Render Parameter、IPC Event、Cookies)

    文章介绍了5种方式,4种是比较常用的: Portlet session IPC Public Render Parameters IPC Event Cookies 参考地址: https://web ...

  6. Angular 学习笔记——模块之间的通讯

    <!DOCTYPE HTML> <html ng-app="myApp"> <head> <meta http-equiv="C ...

  7. Linux学习笔记21——线程同步的两种方式

    一  用信号量同步 1 信号量函数的名字都以sem_开头,线程中使用的基本信号量函数有4个 2 创建信号量 #include<semaphore.h> int sem_init(sem_t ...

  8. 0036 Java学习笔记-多线程-创建线程的三种方式

    创建线程 创建线程的三种方式: 继承java.lang.Thread 实现java.lang.Runnable接口 实现java.util.concurrent.Callable接口 所有的线程对象都 ...

  9. struts2学习笔记--总结获取servletAPI的几种方式

    struts2的Action放弃了request,response等ServletAPI,使得在业务层上更加独立,在有时候使用struts2进行Web开发的时候,不可避免的要在action中使用ser ...

随机推荐

  1. shell脚本中的日期处理

    Ps:这篇文章只是为了做个分类,以后有看到比较好的时间处理命令都会列在这里,您如果有什么好的时间处理命令,可以评论中添加,我会定期查看更新,谢谢! 1.定义一个参数DATE_TODAY,用于记录当天时 ...

  2. linux上安装rz和sz

    简介 lrzsz 官网入口:http://freecode.com/projects/lrzsz/ lrzsz是一个unix通信套件提供的X,Y,和ZModem文件传输协议 windows 需要向ce ...

  3. Bss段的作用及初始化

    初始化的全局变量:数据段 局部变量:栈 malloc:堆 未初始化的全局变量:Bss段 arm-linux-readelf -a 应用程序    可查看文件运行架构.大小端.共享库等信息 初始化Bss ...

  4. Hibrenate实现根据实体类自动创建表或添加字段

    Hibernate支持自动建表,在开发阶段很方便,可以保证hbm与数据库表结构的自动同步. 实现: 在配置hibernate的配置文件中将hbm2ddl.auto设置为update,如:Xml代码&l ...

  5. windows文本操作字符命令含义

    r 打开只读文件,该文件必须存在. r+ 打开可读写的文件,该文件必须存在. rb+ 读写打开一个二进制文件,只允许读写数据. rt+ 读写打开一个文本文件,允许读和写. w 打开只写文件,若文件存在 ...

  6. Kubernetes 编排神器之 Helm

    什么是Kubernetes Helm?为什么要使用Helm? 前言 编写一堆Kubernetes配置文件是一件很麻烦的事情.对于一些容器,我们可能需要10多个yaml文件.维护它们是一个问题,而且在不 ...

  7. python入门导读

    很多培训机构宣称py是人工智能必备的编程语言,打着速成的旗号来引诱学者学习python.事实却并不是这样的,万丈高台平地起,不论你想从事怎样的编程工作,都是从最基本的编程技巧开始的:Python并不适 ...

  8. C# winform 发布的时候没有app.config去哪儿了?

    有时候winform发布的时候app.config不见了? 1.我们来到生成文件的目录下 找到后缀是 .config 的文件右击,打开,也可以用其他方式打卡,我这里使用的是sublime这个文本编辑器 ...

  9. JS实现深拷贝的几种方法

    引 如何区分深拷贝与浅拷贝,简单点来说,就是假设B复制了A,当修改A时,看B是否会发生变化,如果B也跟着变了,说明这是浅拷贝,拿人手短,如果B没变,那就是深拷贝,自食其力. 此篇文章中也会简单阐述到栈 ...

  10. poj 2976 Dropping tests 二分搜索+精度处理

    Dropping tests Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 8349   Accepted: 2919 De ...