基於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

具體的就說到這里了,后續有新的應用,會繼續更新。

源碼下載

點擊這里下載 


 

 

 



 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM