从PRISM开始学WPF(七)MVVM(三)事件聚合器EventAggregator?

Event aggregation. For communication across view models, presenters, or controllers when there is not a direct action-reaction expectation.
(⊙﹏⊙),Google一下:


事件聚合。在没有直接的行动反应期望的情况下,跨视图模型,演示者或控制者进行通信。
1是没有直接行动反应期望,2跨视图通信


在具体了解这个概念之前,先看一个例子:


通过简介,很容易想到聊天窗口,当你在一个视图A中输入文字点击发送之后,另外一个视图B会接收到这个消息,并将文字输出到屏幕上,而这个时候,视图A并不关心谁将收到信息,只管提交,视图B也不管是谁发来的消息,只管接收,并显示。


关门,放代码:


Setp1 在Shell窗口中,定义两个Region,分别来展示发送视图和接收视图


    <Grid>
        <Grid. www.wmyl15.com >
            <ColumnDefinition /www.thd178.com >
            <ColumnDefinition /www.taohuayuan178.com >
        </Grid.ColumnDefinitions>
        <ContentControl prism:RegionManager.RegionName="LeftRegion" />
        <ContentControl Grid.Column="www.wanmeiyuele.cn1" prism:RegionManager.RegionName="RightRegion" />
    </Grid>
今天Typora更新了,代码块支持xaml格式,以前都是用xml-dtd,下面统一使用xaml
XAML


这应该是教程中出现的比较复杂的xaml,比较详细的使用了Grid,这里的Grid很像一个表格,在使用他布局之前,需要定义好列数,下面的代码为Grid设置了两个列


       <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition /www.mcyllpt.com >
        </Grid.ColumnDefinitions>
那么能加行吗?那是当然的了,下面是为Grid添加两行,Height的Auto表示这个行的高度会根据内容高度进行适应:


    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" www.365soke.cn/>
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
在使用Grid的时候,需要为控件指定Grid的位置Grid.Column="1",1就是下标,都是从0开始的,1就代表第二列,当你不指定具体位置的时候,默认将控件插入Grid的0行0列,上面的LeftRegion就是在首行首列的位置。


Setp2 新建两个Module,分别为ModuleA 和 ModuleB,ModuleA中的视图用来发送信息,ModuleB中的视图用来接收显示信息。


Module的创建在第四节已经说明了


先看ModuleA的发送视图:


MessageView.xaml


    <StackPanel>
        <TextBox Text="{Binding Message}"www.dashuju178.com Margin="5"/>
        <Button Command="{Binding SendMessageCommand}" Content="Send Message" Margin="5"/>
    </StackPanel>
MessageView中定义了一个文本框,进行了数据绑定,然后是一个按钮,绑定了一个SendMessageCommand命令。在我们点击Send Message按钮的时候,就会将Message显示到接收视图里去。


再看ModuleB的显示视图:


MessageList.xaml


    <Grid>
        <ListBox ItemsSource="{Binding Messages}" />
    </Grid>
就定义了一个ListBox来显示Message。ItemsSource绑定的应该是一个集合,不然怎么叫Source呢?


接下来,看下Prism怎么实现跨视图模型通讯:


首先,定义一个MessageSentEvent类,继承PubSubEvent<string>,string是因为这个事件接收的payload是字符串类型,PubSubEvent<T>类负责连接发布者和订阅者,他负责维护订阅者列表并处理事件派发给订阅者。


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.www.yongshiyule178.com 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 www.huarenyl.cn_message = "Message to Send";
        public string Message
        {
            get { return _message; }
            set { SetProperty(ref _message, value); }
        }
这是<TextBox Text="{Binding Message}" Margin="5"/>中的Message


然后定义了一个DelegateCommand


public DelegateCommand SendMessageCommand { get; private set; }
接下来就是EventAggregator部分了:


首先定义一个依赖注入点:


IEventAggregator _ea;
然后通过容器的构造注入来获取容器的EventAggregator的实例,还定义了命令SendMessageCommand的回调函数SendMessage。


        public MessageViewModel(IEventAggregator ea)
        {
            _ea = ea;
            SendMessageCommand = new DelegateCommand(SendMessage);
        }
SendMessge中通过MessageSentEvent发布Payload,这里Payload一定要匹配MessageSentEvent的Payload类型,上面我们继承PubSubEvent<string>时使用的String,不然的话,这在编译的时候就会抛出异常。


        private void SendMessage()
        {
            _ea.GetEvent<MessageSentEvent>().Publish(Message);
        }
接下来,我们让ModuleB中的MessageListViewModel获取这个Payload,并进行一些操作:


using Prism.Events;
using Prism.Mvvm;
using System.Collections.www.douniu178.com  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(dasheng178.com/ message);
        }
    }
}
代码阅读:


        private ObservableCollection<string> _messages;
        public ObservableCollection<string> Messages
        {
            get { return _messages; }
            set { SetProperty(ref _messages, value); }
        }
这是 <ListBox ItemsSource="{Binding Messages}" /> 中的Messages,他的类型是ObservableCollection,具体为什么是 ObservableCollection而不是List!后面再说。


        public MessageListViewModel(IEventAggregator ea)
        {
            _ea = ea;
            Messages = new ObservableCollection<string>();


            _ea.GetEvent<MessageSentEvent>().Subscribe(MessageReceived);
        }
这里订阅了MessageSentEvent,并且处理Payload,处理Payload的方法是MessageReceived,这个方法在Messages新增一条记录。


事件聚合器可以有多个发布者和多个订阅者。


标签: Prism, MVVM, ViewModel, Command, EventAggregator
好文要顶 关注我 收藏该文    
丑拒
关注 - 10
粉丝 - 14
+加关注
0 0
« 上一篇:从PRISM开始学WPF(六)MVVM(二)Command?
posted @ 2018-04-03 13:12 丑拒 阅读(25) 评论(0) 编辑 收藏
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值