1. 程式人生 > 其它 >C#-Wpf-Prism.DryIoc-【5】事件聚合器

C#-Wpf-Prism.DryIoc-【5】事件聚合器

【1】先完成基本的環境搭建,可參考C#-WPF-Prism.DryIoc-【1】環境搭建 - 輕吟淺唱,驀然花開 - 部落格園 (cnblogs.com)

【2】事件聚合器可用於跨ViewModel的訊息傳遞,所以我們需要先定義一個訊息實體Message.cs(根據自己的需要寫)放到專案的Events資料夾下,並建立一個MessageEvent繼承於泛型類PubSubEvent。程式碼如下

namespace Wpf_Prism.DryIoc_EventAggregator.Events
{
    public class Message
    {
        public long
Id { get; set; } public string Content { get; set; } } }
using Prism.Events;
namespace Wpf_Prism.DryIoc_EventAggregator.Events
{
    public class MessageEvent:PubSubEvent<Message>
    {
    }
}

【3】本專案結構如下圖,再Views資料夾中建立了View1和View2兩個使用者控制元件和一個窗體MainView,而ViewModels下也分別建立了對應的ViewModel

 

 【4】編輯MainView.xaml 在上面放了三個按鈕並綁定了命令和引數,用來切換頁面和推送訊息

<Window x:Class="Wpf_Prism.DryIoc_EventAggregator.Views.MainView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:prism="http://prismlibrary.com/" xmlns:local="clr-namespace:Wpf_Prism.DryIoc_EventAggregator.Views" prism:ViewModelLocator.AutoWireViewModel="True" mc:Ignorable="d" Title="MainView" Height="450" Width="800"> <DockPanel> <UniformGrid Columns="3" DockPanel.Dock="Top"> <Button Content="開啟View1" Command="{Binding OpenViewCommand}" CommandParameter="View1"/> <Button Content="開啟View2" Command="{Binding OpenViewCommand}" CommandParameter="View2"/> <Button Content="傳送訊息" Command="{Binding SendMessageCommand}"/> </UniformGrid> <ContentControl prism:RegionManager.RegionName="MainContentRegion"/> </DockPanel> </Window>

【5】編輯MainViewModel.cs 新增對應的命令,以及注入需要使用的IRegionManager 和 IEventAggregator介面

using Prism.Commands;
using Prism.Events;
using Prism.Regions;
using Wpf_Prism.DryIoc_EventAggregator.Events;

namespace Wpf_Prism.DryIoc_EventAggregator.ViewModels
{
    public class MainViewModel
    {
        private readonly IRegionManager regionManager;
        private readonly IEventAggregator eventAggregator;

        public DelegateCommand<string> OpenViewCommand { get;private set; }
        public DelegateCommand SendMessageCommand { get;private set; }
        public MainViewModel(IRegionManager regionManager,IEventAggregator eventAggregator)
        {
            this.regionManager = regionManager;
            this.eventAggregator = eventAggregator;
            OpenViewCommand = new DelegateCommand<string>(OpenView);
            SendMessageCommand = new DelegateCommand(SendMessage);
        }

        /// <summary>
        /// 傳送訊息 Hello
        /// </summary>
        private void SendMessage()=> eventAggregator.GetEvent<MessageEvent>().Publish(new Message { Content = "Hello" });

        /// <summary>
        /// 導航
        /// </summary>
        /// <param name="obj"></param>
        private void OpenView(string obj) => regionManager.Regions["MainContentRegion"].RequestNavigate(obj);
    }
}

【6】編輯View1ViewModel 和View2ViewModel程式碼如下

using Prism.Events;
using System.Windows;
using Wpf_Prism.DryIoc_EventAggregator.Events;

namespace Wpf_Prism.DryIoc_EventAggregator.ViewModels
{
    public class View1ViewModel
    {
        private readonly IEventAggregator eventAggregator;

        public View1ViewModel(IEventAggregator eventAggregator)
        {
            this.eventAggregator = eventAggregator;
            //訂閱
            eventAggregator.GetEvent<MessageEvent>().Subscribe(ReceivedMessage);
        }

        /// <summary>
        /// 接收到訊息
        /// </summary>
        /// <param name="obj"></param>
        private void ReceivedMessage(Message obj) => MessageBox.Show("View1收到訊息:" + obj.Content);
    }
}
using Prism.Events;
using System.Windows;
using Wpf_Prism.DryIoc_EventAggregator.Events;

namespace Wpf_Prism.DryIoc_EventAggregator.ViewModels
{
    public class View2ViewModel
    {
        private readonly IEventAggregator eventAggregator;

        public View2ViewModel(IEventAggregator eventAggregator)
        {
            this.eventAggregator = eventAggregator;
            eventAggregator.GetEvent<MessageEvent>().Subscribe(ReceivedMessage);
        }

        private void ReceivedMessage(Message obj)
        {
            MessageBox.Show("View2收到訊息:" + obj.Content+"\r\n後續不會收到訊息");
            //取消訂閱
            eventAggregator.GetEvent<MessageEvent>().Unsubscribe(ReceivedMessage);
        }
    }
}

【7】在app.xaml.cs中將View1,View1ViewModel 和View2 ,View2ViewModel註冊到容器

using Prism.Ioc;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Linq;
using System.Windows;
using Wpf_Prism.DryIoc_EventAggregator.ViewModels;
using Wpf_Prism.DryIoc_EventAggregator.Views;

namespace Wpf_Prism.DryIoc_EventAggregator
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App
    {
        protected override Window CreateShell()
        {
            return Container.Resolve<MainView>();
        }

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            containerRegistry.RegisterForNavigation<View1, View1ViewModel>();
            containerRegistry.RegisterForNavigation<View2, View2ViewModel>();
        }
    }
}

【8】執行專案,效果如下:

完成,謝謝!