从PRISM开始学WPF(七)MVVM(三)事件聚合器EventAggregator-更
原文:
从PRISM开始学WPF(七)MVVM(三)事件聚合器EventAggregator-更新至Prism7.1
事件聚合器EventAggregator[7.1updated]除了app部分,没有任何变化
(⊙﹏⊙),Google一下: 事件聚合。在没有直接的行动反应期望的情况下,跨视图模型,演示者或控制者进行通信。 1是没有直接行动反应期望,2跨视图通信 在具体了解这个概念之前,先看一个例子: 通过简介,很容易想到聊天窗口,当你在一个视图A中输入文字点击发送之后,另外一个视图B会接收到这个消息,并将文字输出到屏幕上,而这个时候,视图A并不关心谁将收到信息,只管提交,视图B也不管是谁发来的消息,只管接收,并显示。 关门,放代码: Setp1 在Shell窗口中,定义两个Region,分别来展示发送视图和接收视图 <Grid> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition /> </Grid.ColumnDefinitions> <ContentControl prism:RegionManager.RegionName="LeftRegion" /> <ContentControl Grid.Column="1" prism:RegionManager.RegionName="RightRegion" /> </Grid>
Setp2 新建两个Module,分别为ModuleA 和 ModuleB,ModuleA中的视图用来发送信息,ModuleB中的视图用来接收显示信息。
先看ModuleA的发送视图:
<StackPanel> <TextBox Text="{Binding Message}" Margin="5"/> <Button Command="{Binding SendMessageCommand}" Content="Send Message" Margin="5"/> </StackPanel> MessageView中定义了一个文本框,进行了数据绑定,然后是一个按钮,绑定了一个SendMessageCommand命令。在我们点击Send Message按钮的时候,就会将Message显示到接收视图里去。 再看ModuleB的显示视图:
<Grid> <ListBox ItemsSource="{Binding Messages}" /> </Grid> 就定义了一个ListBox来显示Message。ItemsSource绑定的应该是一个集合,不然怎么叫Source呢? 接下来,看下Prism怎么实现跨视图模型通讯: 首先,定义一个 using Prism.Events; namespace UsingEventAggregator.Core { public class MessageSentEvent : PubSubEvent<string> { } } 然后我们看下MessageViewModel: using Prism.Commands; using Prism.Events; using Prism.Mvvm; using UsingEventAggregator.Core; namespace ModuleA.ViewModels { public class MessageViewModel : BindableBase { IEventAggregator _ea; 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(IEventAggregator ea) { _ea = ea; SendMessageCommand = new DelegateCommand(SendMessage); } private void SendMessage() { _ea.GetEvent<MessageSentEvent>().Publish(Message); } } } 先看我们熟悉的部分: private string _message = "Message to Send"; public string Message { get { return _message; } set { SetProperty(ref _message,value); } } 这是 然后定义了一个DelegateCommand public DelegateCommand SendMessageCommand { get; private set; } 接下来就是EventAggregator部分了: 首先定义一个IEventAggregator: IEventAggregator _ea; 构造函数: ea是依赖注入容器提供的EventAggregator实例,还定义了命令SendMessageCommand的回调函数 public MessageViewModel(IEventAggregator ea) { _ea = ea; SendMessageCommand = new DelegateCommand(SendMessage); } SendMessge中通过MessageSentEvent发布Payload,这里Payload一定要匹配MessageSentEvent的Payload类型,上面我们继承 private void SendMessage() { _ea.GetEvent<MessageSentEvent>().Publish(Message); } 接下来,我们让ModuleB中的 using Prism.Events; using Prism.Mvvm; using System.Collections.ObjectModel; using UsingEventAggregator.Core; namespace ModuleB.ViewModels { public class MessageListViewModel : BindableBase { IEventAggregator _ea; private ObservableCollection<string> _messages; public ObservableCollection<string> Messages { get { return _messages; } set { SetProperty(ref _messages,value); } } public MessageListViewModel(IEventAggregator ea) { _ea = ea; Messages = new ObservableCollection<string>(); _ea.GetEvent<MessageSentEvent>().Subscribe(MessageReceived); } private void MessageReceived(string message) { Messages.Add(message); } } } 代码阅读: private ObservableCollection<string> _messages; public ObservableCollection<string> Messages { get { return _messages; } set { SetProperty(ref _messages,value); } } 这是 public MessageListViewModel(IEventAggregator ea) { _ea = ea; Messages = new ObservableCollection<string>(); _ea.GetEvent<MessageSentEvent>().Subscribe(MessageReceived); } 这里订阅了MessageSentEvent,并且处理Payload,处理Payload的方法是MessageReceived,这个方法在Messages新增一条记录。 事件聚合器可以有多个发布者和多个订阅者。 作为订阅者,我想订阅特定类型的Payload,上个例子中我只想订阅message里含有Brian的事件,怎么处理呢?Prism为Subscribe方法实现了一个过滤器: _ea.GetEvent<MessageSentEvent>().Subscribe(MessageReceived,ThreadOption.PublisherThread,false,(filter) => filter.Contains("Brian")); 过滤器是一个 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |