Caliburn.Micro学习笔记(三)----事件聚合IEventAggregator和 Ihandle<T>

前端之家收集整理的这篇文章主要介绍了Caliburn.Micro学习笔记(三)----事件聚合IEventAggregator和 Ihandle<T>前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

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;
        }
        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=">
    <StackPanel>
        <TextBox x:Name=StrMessage" Margin=5"/>
        <Button x:Name=OpenOneWin" Content="/>       
        <Button Content=Publish" x:Name="/>
    </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;
        string StrMessage
        {
            get
            {
                return strMessage;
            }
            set
            {
                strMessage = value;
                NotifyOfPropertyChange(() => StrMessage);
            }
        }
       

        [ImportingConstructor]
        public MyMainviewmodel(IEventAggregator e,IWindowManager win)
        {
            _events = e;
            _events.Subscribe(this);
            _windowManager = win;
        }



        void Handle(string message)
        {
            StrMessage = message;
        }
        void Handle(MyMessage message)
        {
            StrMessage = message.ToString();
        }

        #region 
        void Publish()
        {
            _events.Publish(StrMessage);
        }
        #endregion

        #region 打开窗体
        void OpenOneWin()
        {
            OneCviewmodel _one=new OneCviewmodel();
            _windowManager.ShowWindow(_one);
        }
        #endregion

再建一个窗体做接收和广播

它只接收string类型的消息和发布MyMessage类型的消息


<UserControl x:Class=CaliburnIHandle.MyViews.OneCView" xmlns=" xmlns:x=" xmlns:mc=http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d=http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable=d" Height="> <StackPanel> <TextBlock FontSize=13" HorizontalAlignment=Center">1</TextBlock> <TextBox Margin=OneMessage"></TextBox> <Button Margin=OnePublish"/> </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,255); line-height:1.5!important">string>
    {
        readonly IEventAggregator _event;
        string oneMessage;
        string OneMessage
        {
            return oneMessage;
            }
            set
            {
                oneMessage = value;
                NotifyOfPropertyChange(() => OneMessage);
            }
        }
        public OneCviewmodel()
        {
            _event = IoC.Get<IEventAggregator>();
            _event.Subscribe(this);
        }


        void OnePublish()
        {
            _event.Publish(new MyMessage { Str = OneMessage +  One!" });
        }

        string message)
        {
            OneMessage = message;
        }
    }
}


这是一个很简单的例子我们看一下Caliburn.Micro源码它是怎么实现的

看一下IHandle<T>接口

  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类通过

    Subscribes an instance to all events declared through implementations of <see cref = "IHandle{T}" />
        <param name = "subscriber">The instance to subscribe for event publication.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发布相应的消息

          Publishes a message.
        The message instance.</param>
        <remarks>
           Does not marshall the the publication to any special thread by default.
        </remarks>
        void Publish(object message) {
            if (message == message");
            }
            Publish(message,PublicationThreadMarshaller);
        }

        <param name = "marshal">Allows the publisher to provide a custom thread marshaller for the message publication.object message,Action<System.Action> marshal) {
            null){
                if (marshal == 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));
                    }
                }
            });
        }

猜你在找的设计模式相关文章