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="" Width="">
<StackPanel>
<TextBox x:Name="StrMessage" Margin=""/>
<Button x:Name="OpenOneWin" Content="OpenOneWin" Margin=""/>
<Button Content="Publish" x:Name="Publish" Margin=""/>
</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="" Width="">
<StackPanel>
<TextBlock FontSize="" HorizontalAlignment="Center"></TextBlock>
<TextBox Margin="" x:Name="OneMessage"></TextBox>
<Button Margin="" 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));
}
}
});
}

Caliburn.Micro学习笔记(三)----事件聚合IEventAggregator和 Ihandle<T>的更多相关文章

  1. Caliburn.Micro学习笔记目录

    Caliburn.Micro学习笔记(一)----引导类和命名匹配规则 Caliburn.Micro学习笔记(二)----Actions Caliburn.Micro学习笔记(三)----事件聚合IE ...

  2. Caliburn.Micro学习笔记目录——li-peng

    Caliburn.Micro学习笔记(一)----引导类和命名匹配规则 Caliburn.Micro学习笔记(二)----Actions Caliburn.Micro学习笔记(三)----事件聚合IE ...

  3. Caliburn.Micro学习笔记(一)----引导类和命名匹配规则

    Caliburn.Micro学习笔记目录 用了几天时间看了一下开源框架Caliburn.Micro 这是他源码的地址http://caliburnmicro.codeplex.com/ 文档也写的很详 ...

  4. Caliburn.Micro学习笔记(二)----Actions

    Caliburn.Micro学习笔记目录 上一篇已经简单说了一下引导类和简单的控件绑定 我的上一个例子里的button自动匹配到ViewModel事件你一定感觉很好玩吧 今天说一下它的Actions, ...

  5. Caliburn.Micro学习笔记(四)----IHandle<T>实现多语言功能

    Caliburn.Micro学习笔记目录 说一下IHandle<T>实现多语言功能 因为Caliburn.Micro是基于MvvM的UI与codebehind分离, binding可以是双 ...

  6. Caliburn.Micro学习笔记(五)----协同IResult

    Caliburn.Micro学习笔记目录 今天说一下协同IResult 看一下IResult接口 /// <summary> /// Allows custom code to execu ...

  7. 事件聚合IEventAggregator和 Ihandle<T>

    -事件聚合IEventAggregator和 Ihandle<T>   今天 说一下Caliburn.Micro的IEventAggregator和IHandle<T>分成两篇 ...

  8. Caliburn.Micro学习笔记目录——Zhouyongh

    解析Caliburn.Micro(一) 解析Caliburn.Micro(二) 解析Caliburn.Micro(三) 解析Caliburn.Micro(四) Illusion = Caliburn. ...

  9. Caliburn micro 学习笔记...

    页面跳转 LLS 结合 CM 使用方法 事件处理

随机推荐

  1. js的url解析函数封装

    在实际开发中,有些通过get方式与后台交换数据的时候,需要用到的数据在url中,因此就需要我们来获取到url中有用的信息,下面封装的函数已经可以将url解析的很彻底了,可以拿来直接用的: functi ...

  2. 列表屏幕(List Screen)

    声明:原创作品,转载时请注明文章来自SAP师太技术博客( 博/客/园www.cnblogs.com):www.cnblogs.com/jiangzhengjun,并以超链接形式标明文章原始出处,否则将 ...

  3. OpenGL中glVertex、显示列表(glCallList)、顶点数组(Vertex array)、VBO及VAO区别

    OpenGL中glVertex.显示列表(glCallList).顶点数组(Vertex array).VBO及VAO区别 1.glVertex 最原始的设置顶点方法,在glBegin和glEnd之间 ...

  4. 如何将github上的 lib fork之后通过podfile 改变更新源到自己fork的地址

    解决办法: http://stackoverflow.com/questions/20936885/cocoapods-and-github-forks 就是fork完后,提交更改到自己的github ...

  5. UIToolBar

    //UIToolBar 是导航控制器默认隐藏的工具条 //设置UIToolBar的隐藏状态 self.navigationController.toolbarHidden = NO; //如何找到UI ...

  6. [css]我要用css画幅画(五)

    接着之前的[css]我要用css画幅画(四), 这次我给小明和静静增加了对话,用了简单的动画效果. github:https://github.com/bee0060/Css-Paint , 完整代码 ...

  7. asp.net获取服务端和客户端信息

    asp.net获取服务端和客户端信息 获取服务器名:Page.Server.ManchineName获取用户信息:Page.User 获取客户端电脑名:Page.Request.UserHostNam ...

  8. Java虚拟机栈

    Java Virtual Machine Stacks,线程私有,生命周期与线程相同,描述的是Java方法执行的内存模型:每一个方法执行的同时都会创建一个栈帧(Stack Frame),由于存储局部变 ...

  9. Oracle索引梳理系列(八)- 索引扫描类型及分析(高效索引必备知识)

    版权声明:本文发布于http://www.cnblogs.com/yumiko/,版权由Yumiko_sunny所有,欢迎转载.转载时,请在文章明显位置注明原文链接.若在未经作者同意的情况下,将本文内 ...

  10. Linux系统中 安装Vmware Toolst工具

    前提: 安装虚拟机.可以参考:在Windows上安装虚拟机详细图文教程 安装Linux.可以参考:在VMware Workstation里的Linux操作系统的安装——红旗桌面7.0 本文作者:sou ...