wpf Prism中的事件聚合器的封装和使用

在Prism中,有一个重要的功能,就是事件聚合器,也就是消息机制,是大家常用的功能。主要是为了实现不同模块之间的信息交互。在prism的官方demo中也给出了简单的使用例子。但是在实际使用过程中,模块多了,消息多了,会非常的难调试,因此我这里对消息机制做了一次封装,并且统一去管理定义各个模块用到的消息。代码比较简单,我这里只是对官方的例子做了一个改造,大家可以参考一下。红色为主要改动的部分,代码结构如下图:
wpf Prism中的事件聚合器的封装和使用_第1张图片

主要代码如下:
SendMessageMsg.cs

namespace UsingEventAggregator.Core.Messages
{
    public class SendMessageMsg
    {
        public string SendMessage { get; set; }
    }
}

FrameMessenger.cs

using Prism.Events;
using Prism.Ioc;
using System;

namespace UsingEventAggregator.Core
{
    public class FrameMessenger
    {
        private static readonly FrameMessenger _instance = new FrameMessenger();
        private readonly IEventAggregator _eventAggregator;

        public static FrameMessenger Instance
        {
            get { return _instance; }
        }

        private FrameMessenger()
        {
            _eventAggregator = (IEventAggregator)ContainerLocator.Container.Resolve(typeof(IEventAggregator));
        }

        /// 
        /// 发布方法
        /// 
        /// 泛型
        /// T类型消息
        public void Publish<T>(T t)
        {
            _eventAggregator.GetEvent<PubSubEvent<T>>().Publish(t);
        }

        /// 
        /// 订阅T类型消息
        /// 
        /// 泛型
        /// 订阅方法,用于执行接受消息的动作
        public void Subscribe<T>(Action<T> action)
        {
            _ = _eventAggregator.GetEvent<PubSubEvent<T>>().Subscribe(action);
        }

        /// 
        /// 订阅T类型消息,且增加过滤条件
        /// 
        /// 泛型
        /// 订阅方法,用于执行接受消息的动作
        /// 过滤条件
        public void Subscribe<T>(Action<T> action, Predicate<T> filter)
        {
            _ = _eventAggregator.GetEvent<PubSubEvent<T>>().Subscribe(action, filter);
        }

        /// 
        /// 订阅T类型消息,且增加过滤条件,是否同步执行,保持强引用
        /// 
        /// 泛型
        /// 订阅方法,用于执行接受消息的动作
        /// 过滤条件
        /// 是否同步
        /// 是否保持强引用
        public void Subscribe<T>(Action<T> action, Predicate<T> filter = null, bool sync = false, bool keepSubscriberReferenceAlive = false)
        {
            _ = _eventAggregator.GetEvent<PubSubEvent<T>>().Subscribe(action,
                sync ? ThreadOption.PublisherThread : ThreadOption.BackgroundThread,
                keepSubscriberReferenceAlive,
                filter);
        }

        /// 
        /// 取消订阅
        /// 
        /// 泛型
        /// 订阅方法
        public void Unsubscribe<T>(Action<T> action)
        {
            _eventAggregator.GetEvent<PubSubEvent<T>>().Unsubscribe(action);
        }
    }
}

MainWindowViewModel.cs

using Prism.Mvvm;

namespace UsingEventAggregator.ViewModels
{
    public class MainWindowViewModel : BindableBase
    {
        private string _title = "Prism Unity Application";
        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }

        public MainWindowViewModel()
        {

        }
    }
}

MainWindow.xaml

<Window x:Class="UsingEventAggregator.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:prism="http://prismlibrary.com/"
        prism:ViewModelLocator.AutoWireViewModel="True"
        Title="{Binding Title}" Height="350" Width="525">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        Grid.ColumnDefinitions>
        <ContentControl prism:RegionManager.RegionName="LeftRegion" />
        <ContentControl Grid.Column="1" prism:RegionManager.RegionName="RightRegion" />
    Grid>
Window>

MessageViewModel.cs

using Prism.Commands;
using Prism.Mvvm;
using UsingEventAggregator.Core;
using UsingEventAggregator.Core.Messages;

namespace ModuleA.ViewModels
{
    public class MessageViewModel : BindableBase
    {


        private string _message = "Message to Send";
        public string Message
        {
            get { return _message; }
            set { SetProperty(ref _message, value); }
        }

        public DelegateCommand SendMessageCommand { get; private set; }

        public MessageViewModel()
        {
            SendMessageCommand = new DelegateCommand(SendMessage);
        }

        private void SendMessage()
        {
            FrameMessenger.Instance.Publish<SendMessageMsg>(new SendMessageMsg {SendMessage= Message });
        }
    }
}

MessageView.xaml

<UserControl x:Class="ModuleA.Views.MessageView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:prism="http://prismlibrary.com/"             
             prism:ViewModelLocator.AutoWireViewModel="True" Padding="25">
    <StackPanel>
        <TextBox Text="{Binding Message}" Margin="5"/>
        <Button Command="{Binding SendMessageCommand}" Content="Send Message" Margin="5"/>
    StackPanel>
UserControl>

ModuleAModule.cs

using ModuleA.Views;
using Prism.Ioc;
using Prism.Modularity;
using Prism.Regions;

namespace ModuleA
{
    public class ModuleAModule : IModule
    {
        public void OnInitialized(IContainerProvider containerProvider)
        {
            var regionManager = containerProvider.Resolve<IRegionManager>();
            regionManager.RegisterViewWithRegion("LeftRegion", typeof(MessageView));
        }

        public void RegisterTypes(IContainerRegistry containerRegistry)
        {
            
        }
    }
}

MessageListViewModel.cs

using Prism.Events;
using Prism.Mvvm;
using System.Collections.ObjectModel;
using UsingEventAggregator.Core;
using UsingEventAggregator.Core.Messages;

namespace ModuleB.ViewModels
{
    public class MessageListViewModel : BindableBase
    {
       

        private ObservableCollection<string> _messages;
        public ObservableCollection<string> Messages
        {
            get { return _messages; }
            set { SetProperty(ref _messages, value); }
        }

        public MessageListViewModel()
        {
            
            Messages = new ObservableCollection<string>();
            FrameMessenger.Instance.Subscribe<SendMessageMsg>(MessageReceived);
        }

        private void MessageReceived(SendMessageMsg message)
        {
            Messages.Add(message.SendMessage);
        }
    }
}

MessageList.xaml

<UserControl x:Class="ModuleB.Views.MessageList"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:prism="http://prismlibrary.com/"             
             prism:ViewModelLocator.AutoWireViewModel="True" Padding="25">
    <Grid>
        <ListBox ItemsSource="{Binding Messages}" />
    Grid>
UserControl>

ModuleBModule.cs

using ModuleB.Views;
using Prism.Ioc;
using Prism.Modularity;
using Prism.Regions;

namespace ModuleB
{
    public class ModuleBModule : IModule
    {
        public void OnInitialized(IContainerProvider containerProvider)
        {
            var regionManager = containerProvider.Resolve<IRegionManager>();
            regionManager.RegisterViewWithRegion("RightRegion", typeof(MessageList));
        }

        public void RegisterTypes(IContainerRegistry containerRegistry)
        {

        }
    }
}

你可能感兴趣的:(wpf,c#)