C#-Wpf-Prism.DryIoc-【5】事件聚合器
阿新 • • 發佈:2022-04-20
【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 longId { 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】執行專案,效果如下:
完成,謝謝!