zoukankan      html  css  js  c++  java
  • 基于EventAggregator的事件发布及订阅

    EventAggregator简介

    EventAggregator是Prism中专门处理ViewModel与ViewModel之间事件传递的类对象,它提供了针对事件的发布方法和订阅方法,所以可以非常方便的来管理事件。下面的图就是其实现的一个比较简便的说明:

    QQ截图20131105092632

    下面就以一个比较简单的例子来说明其用法,这里我们就在WPF的一个页面上输入用户信息,然后通过点击按钮,让用户信息在同一个页面上输出。

    EventAggregator单页传递数据

    首先,新建一个WPF项目,然后安装好Prism,这里我们可以通过程序包管理器控制台安装,待到都安装好以后,我们就可以开始使用了。

    其次,创建一个GetInputMessages的类,继承自CompositePresentationEvent<string>方法,由于我们传递的都是String类型的数据,所以这里我采用String类型。这个类不提供任何实现,只需要继承就好了:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Practices.Prism.Events;
    
    namespace EventAggregatorPratice
    {
        /// <summary>
        /// 自定义的事件,一定要继承自CompositePresentationEvent类,不做任何实现
        /// </summary>
        public class GetInputMessages:CompositePresentationEvent<string>
        {
        }
    }

    然后,创建EventAggregatorRepository类,这个类主要存储eventAggregator对象并保证其唯一:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using Microsoft.Practices.Prism.Events;
    
    namespace EventAggregatorPratice
    {
        public class EventAggregatorRepository
        {
            public EventAggregatorRepository()
            {
                eventAggregator = new EventAggregator();
            }
    
            public IEventAggregator eventAggregator;
            public static EventAggregatorRepository eventRepository = null;
    
            //单例,保持内存唯一实例
            public static EventAggregatorRepository GetInstance()
            {
                if (eventRepository == null)
                {
                    eventRepository = new EventAggregatorRepository();
                }
                return eventRepository;
            }
        }
    }

    最后则是创建EventAggregatorWindow.xaml窗体,然后编写窗体代码:

    前台的XAML代码如下:

    EventAggregatorWindow.xaml前台布局文件

     后台的代码如下:

    EventAggregatorWindow后台代码

    在这里,我来做一下解释:

    首先,程序先通过SetSubscribe方法来订阅事件,一旦有事件抛出的时候,SetSubscribe便会利用其ReceiveMessage回调方法处理接收到的事件。

    其次,当我们点击按钮的时候,一个SetPublish事件就被抛出了,并且会被SetSubscribe事件接住。效果如图:

    QQ截图20131105094820

    其实现流程就如我上图中画的一样,如果你还是不很明白,我们可以利用C#中常见的Delegate来说明。

    创建一个DelegateWindow.xaml窗体,窗体的前台代码与上面的一致,后台代码如下:

    DelegateWindow后台代码

    在窗体Init的时候,我们注册了回调事件:

    //事件注册,一旦检测到有事件抛出,这里就会接住
     publishEvent += (string value) =>
     {
            txtResult.Text = value;
     };

    这段代码就类似于上面的SetSubscribe()方法,都是为了注册回调事件,以便于处理接收到的信息。

    然后在点击按钮的时候,我们将事件抛出:

     if (publishEvent != null)
         publishEvent(strBuilder.ToString());  //事件抛出

    这段代码就类似于上面的SetPublish(strBuilder.ToString())方法,用于抛出事件.

    所以,看到这里,你是不是已经非常的清楚明了了呢?请看效果图:

    QQ截图20131105095656

    EventAggregator向子页面传递数据

    上面说到的都是单一窗体传值的情况,如果要是传值给子窗体,该如何设计呢?其实,使用方法和上面的示例类似,只不过需要弹出子窗体而已。

    首先,在子窗体FormPostUsingEventAggregatorChild.xaml中,我们由于要接收父窗体传入的值,所以这里应该利用SetSubscribe方法来处理回调事件:

    using System.Windows;
    
    namespace EventAggregatorPratice
    {
        public partial class FormPostUsingEventAggregatorChild : Window
        {
            public FormPostUsingEventAggregatorChild()
            {
                InitializeComponent();
                SetSubscribe();
            }
            public void SetSubscribe()
            {
                EventAggregatorRepository
                    .GetInstance()
                    .eventAggregator
                    .GetEvent<GetInputMessages>()
                    .Subscribe((message) =>
                    {
                        txtResult.Text = message;
                    });
            }
        }
    }
    
    
    而在父窗体FormPostUsingEventAggregator.xaml中,由于要抛出事件,所以我们只需要利用SetPublish抛出事件即可。
    using System;
    using System.Text;
    using System.Windows;
    
    namespace EventAggregatorPratice
    {
        public partial class FormPostUsingEventAggregator : Window
        {
            public FormPostUsingEventAggregator()
            {
                InitializeComponent();
            }
    
            public void SetPublish(string message)
            {
                EventAggregatorRepository
                    .GetInstance()
                    .eventAggregator
                    .GetEvent<GetInputMessages>()
                    .Publish(message);
            }
    
            private void button1_Click(object sender, RoutedEventArgs e)
            {
                //先实例化子窗体
                FormPostUsingEventAggregatorChild child = new FormPostUsingEventAggregatorChild();
                child.Show();
    
                //然后抛出事件
                StringBuilder strBuilder = new StringBuilder();
                strBuilder.Append("用户昵称:").Append(txtNick.Text).Append(Environment.NewLine);
                strBuilder.Append("用户年龄:").Append(txtAge.Text).Append(Environment.NewLine);
                strBuilder.Append("用户性别:").Append(txtSex.Text).Append(Environment.NewLine);
                strBuilder.Append("用户电话:").Append(txtTel.Text).Append(Environment.NewLine);
                strBuilder.Append("用户住址:").Append(txtAddress.Text).Append(Environment.NewLine);
                SetPublish(strBuilder.ToString());
            }
        }
    }
    
    

    需要说明一下的是,子窗体一定要先显示,然后才能够抛出事件,否则会因为子窗体无法接收事件而导致父窗体抛出的事件丢失。运行效果如下:

    父窗体输入:

    QQ截图201311051003061

    子窗体接收:

    QQ截图201311051003112

    具体的就说到这里了,后续有新的应用,会继续更新。

    源码下载

    点击这里下载 


     



     

     
  • 相关阅读:
    Elasticsearch 索引操作
    windows curl命令
    Elasticsearch简介
    ElasticSearch插件安装
    SignalR实时聊天功能
    原来现在很多人都用SignalR来实现Chat Room
    设计模式(六)(Command Pattern)命令模式
    FtpWebRequest FTP异步下载、异步上传文件
    FTP规范
    oracle组建:ODAC112021Xcopy_x64,在开发机上,不用安装oracle的客户端等开发
  • 原文地址:https://www.cnblogs.com/scy251147/p/3407983.html
Copyright © 2011-2022 走看看