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

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

主要代码如下:
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));
        }

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

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

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

        /// <summary>
        /// 订阅T类型消息,且增加过滤条件,是否同步执行,保持强引用
        /// </summary>
        /// <typeparam name="T">泛型</typeparam>
        /// <param name="action">订阅方法,用于执行接受消息的动作</param>
        /// <param name="filter">过滤条件</param>
        /// <param name="sync">是否同步</param>
        /// <param name="keepSubscriberReferenceAlive">是否保持强引用</param>
        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);
        }

        /// <summary>
        /// 取消订阅
        /// </summary>
        /// <typeparam name="T">泛型</typeparam>
        /// <param name="action">订阅方法</param>
        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)
        {

        }
    }
}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值