Caliburn.Micro学习笔记(三)----事件聚合IEventAggregator和 IhandleT
Caliburn.Micro学习笔记目录
今天 说一下Caliburn.Micro的IEventAggregator和IHandle<T>分成两篇去讲这一篇写一个简单的例子
看一它的的实现和源码
下一篇用它们做一个多语言的demo
这两个是事件的订阅和广播,很强大,但用的时候要小心发生不必要的冲突。
先看一下它的实现思想
在Caliburn.Micro里EventAggregator要以单例的形式出现这样可以做到对广播做到统一的管理
对象实现IHand<T>接口后通过EventAggregator的subsribe方法把自己加入到Handler集合中这样就能接叫信息
能过EventAggregator.Publish(object obj)方法去发送广播
源码: CaliburnIHandle.rar
先看一下个小demo再去分析它的源码是怎么实现的
效果
先写一个消息类,这个类只是做一个IHandle<T>的类型应用没有什么实际意义
class MyMessage{public string Str{get;set;}public override string ToString(){return Str;}}
建一个窗体MainView和一个ViewModel类
<Window x:Class="CaliburnIHandle.MyViews.MyMainView"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="MyMainView" Height="300" Width="300"><StackPanel><TextBox x:Name="StrMessage" Margin="5"/><Button x:Name="OpenOneWin" Content="OpenOneWin" Margin="5"/> <Button Content="Publish" x:Name="Publish" Margin="5"/></StackPanel> </Window>
窗体有一个textBox显示消息。一个button打开窗体一个发布消息
再看一下ViewModel
实现 了两个IHandle<T> 一个是string 类型一个是我们自己定义的MyMessage
MainViewMode发布string类型的广播也接收string类型和MyMessage类型的消息
[Export(typeof(IShell))]class MyMainViewModel : PropertyChangedBase, IHandle<string>,IHandle<MyMessage>{readonly IEventAggregator _events;readonly IWindowManager _windowManager;string strMessage;public string StrMessage{get{return strMessage;}set{strMessage = value;NotifyOfPropertyChange(() => StrMessage);}}[ImportingConstructor]public MyMainViewModel(IEventAggregator e,IWindowManager win){_events = e;_events.Subscribe(this);_windowManager = win;}public void Handle(string message){StrMessage = message;}public void Handle(MyMessage message){StrMessage = message.ToString();}#region public void Publish(){_events.Publish(StrMessage);}#endregion#region 打开窗体public void OpenOneWin(){OneCViewModel _one=new OneCViewModel();_windowManager.ShowWindow(_one);}#endregion
再建一个窗体做接收和广播
它只接收string类型的消息和发布MyMessage类型的消息
<UserControl x:Class="CaliburnIHandle.MyViews.OneCView"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" Height="300" Width="300"><StackPanel><TextBlock FontSize="13" HorizontalAlignment="Center">1</TextBlock><TextBox Margin="5" x:Name="OneMessage"></TextBox><Button Margin="5" x:Name="OnePublish" Content="Publish"/></StackPanel> </UserControl>
using Caliburn.Micro; using CaliburnIHandle.CommonC; using System; using System.Collections.Generic; using System.ComponentModel.Composition; using System.Linq; using System.Text;namespace CaliburnIHandle.MyViewModels {[Export(typeof(OneCViewModel))]class OneCViewModel : PropertyChangedBase, IHandle<string>{readonly IEventAggregator _event;string oneMessage;public string OneMessage{get{return oneMessage;}set{oneMessage = value;NotifyOfPropertyChange(() => OneMessage);}}public OneCViewModel(){_event = IoC.Get<IEventAggregator>();_event.Subscribe(this);}public void OnePublish(){_event.Publish(new MyMessage { Str = OneMessage + " One!" });}public void Handle(string message){OneMessage = message;}} }
这是一个很简单的例子我们看一下Caliburn.Micro源码它是怎么实现的
看一下IHandle<T>接口
public interface IHandle<TMessage> : IHandle { //don't use contravariance here/// <summary>/// Handles the message./// </summary>/// <param name = "message">The message.</param>void Handle(TMessage message);}
IHandle<T>只有一个处理T事件的的方法
EventAggregator类通过
/// <summary>/// Subscribes an instance to all events declared through implementations of <see cref = "IHandle{T}" />/// </summary>/// <param name = "subscriber">The instance to subscribe for event publication.</param>public virtual void Subscribe(object subscriber) {if (subscriber == null) {throw new ArgumentNullException("subscriber");}lock(handlers) {if (handlers.Any(x => x.Matches(subscriber))) {return;}handlers.Add(new Handler(subscriber));}}
把订阅的类放到Handlers集合里
再通过Publish发布相应的消息
/// <summary>/// Publishes a message./// </summary>/// <param name = "message">The message instance.</param>/// <remarks>/// Does not marshall the the publication to any special thread by default./// </remarks>public virtual void Publish(object message) {if (message == null) {throw new ArgumentNullException("message");}Publish(message, PublicationThreadMarshaller);}/// <summary>/// Publishes a message./// </summary>/// <param name = "message">The message instance.</param>/// <param name = "marshal">Allows the publisher to provide a custom thread marshaller for the message publication.</param>public virtual void Publish(object message, Action<System.Action> marshal) {if (message == null){throw new ArgumentNullException("message");}if (marshal == null) {throw new ArgumentNullException("marshal");}Handler[] toNotify;lock (handlers) {toNotify = handlers.ToArray();}marshal(() => {var messageType = message.GetType();var dead = toNotify.Where(handler => !handler.Handle(messageType, message)).ToList();if(dead.Any()) {lock(handlers) {dead.Apply(x => handlers.Remove(x));}}});}
转载于:https://www.cnblogs.com/li-peng/p/3431035.html
Caliburn.Micro学习笔记(三)----事件聚合IEventAggregator和 IhandleT相关推荐
- Caliburn.Micro学习笔记目录——li-peng
Caliburn.Micro学习笔记(一)----引导类和命名匹配规则 Caliburn.Micro学习笔记(二)----Actions Caliburn.Micro学习笔记(三)----事件聚合IE ...
- Caliburn.Micro学习笔记(二)----Actions
Caliburn.Micro学习笔记目录 上一篇已经简单说了一下引导类和简单的控件绑定 我的上一个例子里的button自动匹配到ViewModel事件你一定感觉很好玩吧 今天说一下它的Actions, ...
- Caliburn.Micro学习笔记目录——Zhouyongh
解析Caliburn.Micro(一) 解析Caliburn.Micro(二) 解析Caliburn.Micro(三) 解析Caliburn.Micro(四) Illusion = Caliburn. ...
- Caliburn.Micro学习笔记目录——其他
Caliburn.Micro - IResult and Coroutines 转载于:https://www.cnblogs.com/SkunkHusband/p/5196933.html
- J2EE学习笔记三:EJB基础概念和知识 收藏
J2EE学习笔记三:EJB基础概念和知识 收藏 EJB正是J2EE的旗舰技术,因此俺直接跳到这一章来了,前面的几章都是讲Servlet和JSP以及JDBC的,俺都懂一些.那么EJB和通常我们所说的Ja ...
- Mr.J-- jQuery学习笔记(三十二)--jQuery属性操作源码封装
扫码看专栏 jQuery的优点 jquery是JavaScript库,能够极大地简化JavaScript编程,能够更方便的处理DOM操作和进行Ajax交互 1.轻量级 JQuery非常轻巧 2.强大的 ...
- SurfaceFlinger学习笔记(三)之SurfaceFlinger进程
概述 本系列是基于android Q 即android10 SurfaceFlinger学习笔记(一)应用启动流程 SurfaceFlinger学习笔记(二)之Surface SurfaceFling ...
- MySQL学习笔记(三)查询
写在前面:本篇为作者自学总结,学习内容为课堂所学和网络学习笔记汇总,对于内容引用部分在文中和文末注明. 文章仅供参考,如需深入了解,请查阅MySQL参考手册.附上下载链接: 链接:https://pa ...
- OpenCasCade学习笔记(三):加载显示STEP格式图片,并实现平移、缩放和旋转操作
OpenCasCade学习笔记(三):加载显示STEP格式图片,并实现平移.缩放和旋转操作 C3DWidget.h #pragma once#include <QtWidgets/QApplic ...
最新文章
- C#判断年份是否为闰年
- R语言实战第一,二章SQL版
- java 网络传输中发送byte[]和接收到的不一致_为什么JAVA对象需要实现序列化?
- 求字典key的和python_python怎么将字典key相同的value值, 合并
- 想提高运维效率,那就把MySQL数据库部署到Kubernetes 集群中
- 【AD】AD19/20笔记及快捷键
- Python-视频爬取示例对小白友好
- 连接串口_气压计PTB330连接HMI串口屏
- opencv-api warpPerspective
- 超棒的一遍综述性博客
- 【训练题】分队 P1672
- 为什么感觉农村人在城里工作后,大部分都变了?
- python和java学哪个好-Python VS Java,学哪个更有前途?
- 计算机硕论题目,硕士论文题目精选(计算机方向)
- 项目管理软件 OpenProj
- bind搭建智能DNS
- 解读生命密码的基本手段——DNA测序技术的前世今生
- qq音乐网络异常获取音乐失败_QQ音乐无法播放_为什么qq音乐总是提示歌曲无效或网络连接失败?...
- 中国石油大学《微观经济学》第一次在线作业
- semi-suppervised learning 半监督学习
热门文章
- 【Tools】Xshell6安装和卸载图解教程
- php修改数组元素,php数组特定元素修改方法
- Docker Centos 7.X部署Tomcat 并且修改Server.xml配置文件方案 并设置时区 只要十一步
- Codeforces 1480A. Yet Another String Game (阅读理解题)
- Kali更新源 - 由于没有公钥,无法验证下列签名: NO_PUBKEY ED444FF07D8D0BF6
- HDU - 4461 The Power of Xiangqi
- QT之error: cannot bind non-const lvalue reference of type ‘CBaowen’ to an rvalue of type ‘CBaowen
- pygame中Rect(left, top, width, height)的参数详解
- rpm方式安装mysql-5.7.11
- [BUUCTF-pwn]——ciscn_2019_n_5