【学习笔记】Silverlight框架:Jounce(4)——事件通信

Prism、CM和Jounce里都有各自的事件通信机制,也都叫EventAggregator。

相比于Prism,Jounce里的EventAggregator的风格更接近CM。当然作者也是这么说的:The pattern here is based on the lightweight version Rob Eisenburg introduced with Caliburn Micro。

这里涉及的类主要有三个:两个接口类IEventAggregator和IEventSink<in T>,还有实现IEventAggregator的EventAggregatorService。

IEventAggregator定义了四个方法,其中三个是订阅消息、在UI线程上订阅消息和取消订阅,接受的参数都是IEventSink;最后一个方法是用来发布消息的。

EventAggregatorService内部维护了一个弱引用的字典用来存储订阅了消息的IEventSink,当在某个地方谁谁谁发布消息的时候,就会在这个字典里去找泛型类型匹配的IEventSink并调用其唯一的一个方法HandleEvent。

其实就是观察者,你懂的。

来实例操作下,通过模板新建解决方案,整个结构如下:

MainPage分为左右2个部分,分别用来存放PublishIntSubscribeGuid和PublishGuidSubscribeInt。

PublishIntSubscribeGuid会发布Int值,然后接收Guid的消息。

PublishGuidSubscribeInt会发布Guid,然后接收Int值的消息。

两个页面都是上面一个按钮,下面一个TextBox用来显示收到的消息,后台代码也差不多,我们来看看其中一个:

    [Export]
    public partial class PublishIntSubscribeGuid : UserControl, IEventSink<Guid>, IPartImportsSatisfiedNotification
    {
        [Import]
        public IEventAggregator EventAggregator { get; set; }

        public PublishIntSubscribeGuid()
        {
            InitializeComponent();
            this.PublishButton.Click += new RoutedEventHandler(PublishButton_Click);
        }

        void PublishButton_Click(object sender, RoutedEventArgs e)
        {
            var random = new Random();
            this.EventAggregator.Publish(random.Next());
        }

        #region IPartImportsSatisfiedNotification 成员

        public void OnImportsSatisfied()
        {
            EventAggregator.SubscribeOnDispatcher(this);
        }

        #endregion

        #region IEventSink<Guid> 成员

        public void HandleEvent(Guid publishedEvent)
        {
            this.OutTextBox.Text += "\r\n" + publishedEvent;
        }

        #endregion
    }

首先,要订阅Guid类型的消息先要实现IEventSink接口,泛型类型是Guid。

然后,要实现IPartImportsSatisfiedNotification接口,在MEF导入IEventAggregator后,注册完成消息订阅(这里在UI线程上订阅),这样当有某个地方发布类型是GUID的消息时,HandleEvent(Guid publishedEvent)方法就会最终被调用。

另外,在点击发布消息的按钮时候发布个随机的Int值,当某个地方订阅了Int类型的消息时,那个地方就会接收到这个随机值。

实际应用可能要复杂点,泛型会是某个实体类或者某种错误等等。

看一下效果:

代码:这里

PS:

1.打开APP.CS,可以看到通过模板创建的解决方案默认使APP实现了 IEventSink<UnhandledExceptionEvent>接口,这个就是原来通过Application.Current.UnhandledException注册的系统未处理错误,Jounce在ApplicationService里进行了注册和转换并通过事件系统进行了发布。这样就可以在别的地方也进行侦听。

2.整个事件通信系统是Jounce页面加载和导航的基础,可以实现IEventSink<ViewNavigationArgs>并侦听下看看。


posted @ 2011-07-28 23:33  超时空饭盒  阅读(1384)  评论(0编辑  收藏  举报