在本篇文章中主要讲解在Prism中模块与模块之间事件关联的机制。在这里牵涉到三个名词:事件定义,事件发布,事件订阅。

第一:事件定义

在公共类库中定义事件。

①没有参数事件

public class NullClass { }

public class NullableEvent : CompositePresentationEvent<NullClass> { }

②简单类型参数事件

public class MessageAddedEvent : CompositePresentationEvent<string> { }

③复合类型参数事件

  public class News
    {
        /// <summary>
        /// 标题。
        /// </summary>
        public string Title { get; set; }
        /// <summary>
        /// 内容。
        /// </summary>
        public string Content { get; set; }
    }

public class NewsAddedEvent : CompositePresentationEvent<News> { }

第二:事件发布(以下为示例代码)

using Microsoft.Practices.Composite.Events;
using PrismEvent.Infrastructure;
using System.Windows;
using System.Windows.Controls; namespace PrismEvent.Publisher
{
/// <summary>
/// PublisherView.xaml 的交互逻辑
/// </summary>
public partial class PublisherView : UserControl
{
IEventAggregator eventAggregator;
/// <summary>
/// 构造函数。
/// </summary>
public PublisherView()
{
InitializeComponent();
}
/// <summary>
/// 构造函数。
/// </summary>
/// <param name="eventAggregator">事件聚合。</param>
public PublisherView(IEventAggregator eventAggregator)
: this()
{
this.eventAggregator = eventAggregator;
}
/// <summary>
/// 简单参数。
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnSimpleParam_Click(object sender, RoutedEventArgs e)
{
string message = "Hellow world";
eventAggregator.GetEvent<MessageAddedEvent>().Publish(message);
}
/// <summary>
/// 复合参数。
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void btnCompositeParam_Click(object sender, RoutedEventArgs e)
{
News news = new News()
{
Title = "Bao's demo was published.",
Content = "This message is wonderful."
};
eventAggregator.GetEvent<NewsAddedEvent>().Publish(news);
} private void btnWithoutParam_Click(object sender, RoutedEventArgs e)
{
eventAggregator.GetEvent<NullableEvent>().Publish(null);
} private void btnStandard_Click(object sender, RoutedEventArgs e)
{
string message = "Open seasame!";
eventAggregator.GetEvent<StandardMessageAddedEvent>().Publish(message);
}
}
}

第三:事件订阅

using Microsoft.Practices.Composite.Events;
using Microsoft.Practices.Composite.Presentation.Events;
using PrismEvent.Infrastructure;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes; namespace PrismEvent.Subscriber
{
/// <summary>
/// Subscriberview.xaml 的交互逻辑
/// </summary>
public partial class Subscriberview : UserControl
{
IEventAggregator eventAggregator;
private SubscriptionToken subscriptionToken;
public Subscriberview()
{
InitializeComponent();
} public Subscriberview(IEventAggregator eventAggregator)
: this()
{
this.eventAggregator = eventAggregator;
this.eventAggregator.GetEvent<MessageAddedEvent>().Subscribe(ShowMessage);
this.eventAggregator.GetEvent<NewsAddedEvent>().Subscribe(ShowMessage);
this.eventAggregator.GetEvent<NullableEvent>().Subscribe(DoSomething);
StandardMessageAddedEvent messageAddedEvent = eventAggregator.GetEvent<StandardMessageAddedEvent>();
if (subscriptionToken != null)
{
messageAddedEvent.Unsubscribe(subscriptionToken);
}
subscriptionToken = messageAddedEvent.Subscribe(ShowMessage2, ThreadOption.UIThread, true, Filter);
} private bool Filter(string message)
{
return true;
} private void ShowMessage2(string message)
{
this.tbSimpleParam.Text = message;
StandardMessageAddedEvent messageAddedEvent = eventAggregator.GetEvent<StandardMessageAddedEvent>();
if (subscriptionToken != null)
{
messageAddedEvent.Unsubscribe(subscriptionToken);
}
} private void DoSomething(NullClass obj)
{ }
/// <summary>
/// 显示新闻消息。
/// </summary>
/// <param name="news">新闻对象。</param>
private void ShowMessage(News news)
{
this.tbSimpleParam.Text = news.Title;
}
/// <summary>
/// 显示消息。
/// </summary>
/// <param name="message">消息内容。</param>
private void ShowMessage(string message)
{
this.tbSimpleParam.Text = message;
} }
}

对于事件的订阅,正规的写法如下所示:

StandardMessageAddedEvent messageAddedEvent = eventAggregator.GetEvent<StandardMessageAddedEvent>();

            if (subscriptionToken != null)

            {

                messageAddedEvent.Unsubscribe(subscriptionToken);

            }

            subscriptionToken = messageAddedEvent.Subscribe(ShowMessage2, ThreadOption.UIThread, true, Filter);

在上面的代码中,我们看到这样的顺序:

1.先从IEventAggregator中获取注册到其中的事件对象,也就是messageAddedEvent;

StandardMessageAddedEvent messageAddedEvent=eventAggregator.GetEvent<StandardMessageAddedEvent>();

2.这个messageAddedEvent对象具有Subscribe方法,它返回一个SubscriptionToken类型的对象,用来标志事件触发后,在订阅一方所调用的方法:

subscriptionToken=messageAddedEvent.Subscribe(ShowMessage2,ThreadOption.UIThread,true,Filter);

3.在第2步之前,我们需要检查SubscriptionToken对象是否为空,否则就要注销之前的messageAddedEventHandler方法。

if(subscriptionToken!=null)

{

messageAddedEvnet.Unsubscribe(subscriptionToken);

}

之所以这么写,是因为系统弱引用后的垃圾自动回收时间,于是,将Subscribe方法的第三个参数设置为true(默认为false,弱引用,垃圾自动回收)。这样,订阅的就是强引用了,Prism就会要求我们必须手动取消事件的订阅。

在Subscribe方法中,第二个参数是ThreadOption枚举。值有:

publisherThread     //在publisherThread所在线程上执行,默认值。

UIThread               //在UI线程上触发。

BackgroundThread //在后台线程上异步调用。

第四个参数是一个bool类型的委托,它以事件传递的消息类型作为参数。

subscriptionToken=messageAddedEvent.Subscribe(ShowMessage2,ThreadOption.UIThread,true,Filter);

public bool Filter(string text){

return true;

}

注意:Filter方法总会在ShowMessage2方法前执行。如果返回true,则执行ShowMessage2。若为false则不执行。

在此,Prism的事件机制告一段落。

Prism for WPF 第一讲 Event机制的更多相关文章

  1. Prism for WPF再探(基于Prism事件的模块间通信)

    上篇博文链接 Prism for WPF初探(构建简单的模块化开发框架) 一.简单介绍: 在上一篇博文中初步搭建了Prism框架的各个模块,但那只是搭建了一个空壳,里面的内容基本是空的,在这一篇我将实 ...

  2. Prism for WPF 搭建一个简单的模块化开发框架(五)添加聊天、消息模块

    原文:Prism for WPF 搭建一个简单的模块化开发框架(五)添加聊天.消息模块 中秋节假期没事继续搞了搞 做了各聊天的模块,需要继续优化 第一步画页面 页面参考https://github.c ...

  3. Prism for WPF

    Prism for WPF Prism for WPF初探(构建简单的模块化开发框架)   先简单的介绍一下Prism框架,引用微软官方的解释: Prism provides guidance to ...

  4. Prism for WPF 搭建一个简单的模块化开发框架(四)异步调用WCF服务、WCF消息头添加安全验证Token

    原文:Prism for WPF 搭建一个简单的模块化开发框架(四)异步调用WCF服务.WCF消息头添加安全验证Token 为什么选择wcf?   因为好像wcf和wpf就是哥俩,,, 为什么选择异步 ...

  5. Prism for WPF 搭建一个简单的模块化开发框架(三) 给TreeView加样式做成菜单

    原文:Prism for WPF 搭建一个简单的模块化开发框架(三) 给TreeView加样式做成菜单 昨天晚上把TreeView的样式做了一下,今天给TreeView绑了数据,实现了切换页面功能 上 ...

  6. 好玩的WPF第一弹:窗口抖动+边框阴影效果+倒计时显示文字

    原文:好玩的WPF第一弹:窗口抖动+边框阴影效果+倒计时显示文字 版权声明:转载请联系本人,感谢配合!本站地址:http://blog.csdn.net/nomasp https://blog.csd ...

  7. 干货|漫画算法:LRU从实现到应用层层剖析(第一讲)

    今天为大家分享很出名的LRU算法,第一讲共包括4节. LRU概述 LRU使用 LRU实现 Redis近LRU概述 第一部分:LRU概述 LRU是Least Recently Used的缩写,译为最近最 ...

  8. CS193P - 2016年秋 第一讲 课程简介

    Stanford 的 CS193P 课程可能是最好的 ios 入门开发视频了.iOS 更新很快,这个课程的最新内容也通常是一年以内发布的. 最新的课程发布于2016年春季.目前可以通过 iTunes ...

  9. POI教程之第一讲:创建新工作簿, Sheet 页,创建单元格

    第一讲 Poi 简介 Apache POI 是Apache 软件基金会的开放源码函数库,Poi提供API给java程序对Microsoft Office格式档案读和写的功能. 1.创建新工作簿,并给工 ...

随机推荐

  1. bzoj 1226 [SDOI2009]学校食堂Dining(状压DP)

    Description 小F 的学校在城市的一个偏僻角落,所有学生都只好在学校吃饭.学校有一个食堂,虽然简陋,但食堂大厨总能做出让同学们满意的菜肴.当然,不同的人口味也不一定相同,但每个人的口味都可以 ...

  2. 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程

    数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...

  3. c语言 字符版 简易2048

    花了两个多小时,用最蠢的方法写的……最简陋版…… 还不确定这么写逻辑对不对…… #include <iostream> #include <cstdio> #include & ...

  4. PC问题-使用BAT方法设置IP地址

    ::------以下为批处理文件内容---- @echo off ::set slection1= set/p slection1=请输入IP地址: netsh interface ip set ad ...

  5. oc学习之路----代理模式

    今天刚学完oc的代理模式,觉得有点新奇,第一次接触,原理 A完成一件事,但是自己不能完成,于是他找个代理人B 替他完成这个事情,他们之间便有个协议 (protocol),B继承该协议来完成A代理给他的 ...

  6. Yii2 多域名跨域同步登录退出

    在平台开发过程中,项目分为前台(frontend)www.xxx.com和后台(backend) yun.xxx.com两部分,绑定两个域名, 我们知道在没有绑定域名的时候前后台可以同步登录和退出,但 ...

  7. 多点触控之MotionEvent.ACTION_MASK作用

    ACTION_MASK在Android中是应用于多点触摸操作,字面上的意思大概是动作掩码的意思吧. 在onTouchEvent(MotionEvent event)中,使用switch (event. ...

  8. HTTP POST发消息

    业务需求:模拟TANX给DSP发消息,protobuf数据已弄好. 代码: def PostDataToDSP(self,url,postdata): headers = { #taobao文档规定 ...

  9. nginx安装php和php-fpm

    最近在学习nginx,看了好多帖子终于安装成功了. 经验,首先不要用yum安装,安装完以后根本找不到安装目录在哪里呀,然后安装失败以后会很不方便. 最终选择了自己编译安装. 看了好多帖子都不行,终于找 ...

  10. GNOME3启动时出错:Oh no! Something has gone wrong.Logout!

    今天用虚拟机安装debian7.1,在启动的时候遇到登录失败的问题,用GNOME Classic可以登录,特地记录如下: 原文出处:http://r3dux.org/2011/11/how-to-fi ...