0523 事件聚合器

29 篇文章 0 订阅

详细

https://www.cnblogs.com/joean/tag/wpf/

 

 

https://blog.csdn.net/qq_45076638/article/details/90448930

 

https://blog.csdn.net/csdnnews/article/details/90425646

 

http://www.captainbed.net/csdn/

 

https://blog.csdn.net/android_bar/article/details/84073142

 public DelegateCommand CmdExecute { get; set; }

CmdExecute = new DelegateCommand(Execute);

private void Execute()
{
      eventAggregator.GetEvent<ExecuteEvent>().Publish(TabIndex);
}

eventAggregator.GetEvent<ExecuteEvent>().Subscribe(Execute);

 

Prism模块之间通信的几种方式

在开发大型复杂系统时,我们通常会按功能将系统分成很多模块,这样模块就可以独立的并行开发、测试、部署、修改。使用Prism框架设计表现层时,我们也会遵循这个原则,按功能相关性将界面划分为多个模块,每个模块又包含多个Region。这就需要解决模块之间、Region之间经常需要进行通信的问题,Prism提供了以下几种方式:

1、聚合事件(Event aggregation

使用方式,先在一个公共模块中定义一个事件MyEvent ,传输数据为MyEntity。

public class MyEvent : CompositePresentationEvent<MyEntity> { }

然后在需要等待处理事件的模块中订阅事件,如下所示:

private IEventAggregator eventAggregator;

eventAggregator = (IEventAggregator)ServiceLocator.Current.GetService(typeof(IEventAggregator));

eventAggregator.GetEvent<MyEvent>().Subscribe(MyEventHandler, true);

public void MyEventHandler(MyEntity myEntity) {

}

eventAggregator 相当于一个全局的集合,保存了所有订阅的事件。

在发起通信的模块中发布事件,如下所示:

eventAggregator.GetEvent<CreatePlanEvent>().Publish(new MyEntity());

https://www.cnblogs.com/candyzkn/p/4515158.html

https://www.cnblogs.com/scy251147/p/3407983.html

public class EARepository
    {
        public EARepository()
        {
            eventAggregator = new EventAggregator();
        }

        public IEventAggregator eventAggregator;
        public static EARepository eventRepository = null;

        //单例,保持内存唯一实例
        public static EARepository GetInstance()
        {
            if (eventRepository == null)
            {
                eventRepository = new EARepository();
            }
            return eventRepository;
        }
    }

 

 

<Grid>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition></RowDefinition>
                <RowDefinition></RowDefinition>
                <RowDefinition></RowDefinition>
            </Grid.RowDefinitions>
            <TextBox  Grid.Row="0" x:Name="txtsend" Margin="5" TextWrapping="Wrap" AcceptsReturn="True" VerticalScrollBarVisibility="Visible"/>
            <Button Grid.Row="1"  Content="发送消息"  Background="LightBlue"  Click="Button_Click"/>
            <TextBox Background="LightGray" x:Name="txtre" Grid.Row="2" TextWrapping="Wrap" AcceptsReturn="True" VerticalScrollBarVisibility="Visible"/>
        </Grid>
    </Grid>

  public partial class UCMessageView : UserControl
    {
        public UCMessageView()
        {
            InitializeComponent();
            SetSubscribe();
        }


        public void SetPublish(string messageData)
        {
            EARepository.GetInstance().eventAggregator.GetEvent<GetInputMessages>().Publish(messageData);
        }

        public void SetSubscribe()
        {
            EARepository.GetInstance().eventAggregator.GetEvent<GetInputMessages>().Subscribe(ReceiveMessage);
        }

        public void ReceiveMessage(string messageData)
        {
            this.txtre.Text = messageData;

        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            SetPublish(this.txtsend.Text);
        }
    }

 

 <Grid>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition></RowDefinition>
                <RowDefinition></RowDefinition>
                <RowDefinition></RowDefinition>
            </Grid.RowDefinitions>
            <TextBox Background="LightPink" x:Name="txtresult" Grid.Row="1" TextWrapping="Wrap" AcceptsReturn="True" VerticalScrollBarVisibility="Visible" Margin="45,0,74,0"/>
            <TextBox Background="LightCoral" x:Name="txtresult1" Grid.Row="0" TextWrapping="Wrap" AcceptsReturn="True" VerticalScrollBarVisibility="Visible" Margin="45,0,74,0"/>
            <TextBox Background="LightCyan" x:Name="txtresult2" Grid.Row="2" TextWrapping="Wrap" AcceptsReturn="True" VerticalScrollBarVisibility="Visible" Margin="45,0,74,0"/>
        </Grid>
    </Grid>

 public class GetInputMessages : PubSubEvent<string>
    {
    }

public partial class UCMessageList : UserControl
    {
        public UCMessageList()
        {
            InitializeComponent();
            SetSubscribe();
        }
        public void SetSubscribe()
        {
            EARepository.GetInstance().eventAggregator.GetEvent<GetInputMessages>().Subscribe((message) =>
            {
                this.txtresult.Text = message;
                this.txtresult1.Text = message;
                this.txtresult2.Text = message;
            });
        }

 

eventAggregator.GetEvent<ExecuteEvent>().Publish(TabIndex);
eventAggregator.GetEvent<ExecuteEvent>().Subscribe(Execute);
eventAggregator.GetEvent<ExecuteEvent>().Subscribe(Execute);
eventAggregator.GetEvent<ExecuteEvent>().Subscribe(Execute);
eventAggregator.GetEvent<ExecuteEvent>().Subscribe(Execute);
eventAggregator.GetEvent<ExecuteEvent>().Subscribe(Execute);
eventAggregator.GetEvent<ExecuteEvent>().Subscribe(Execute);
eventAggregator.GetEvent<ExecuteEvent>().Subscribe(Execute);

 

 

对于最小订阅或默认订阅,订阅者必须提供具有接收事件通知的适当签名的回调方法。例如,TickerSymbolSelectedEvent的处理程序要求该方法采用字符串参数,如此处所示。

eventAggregator.GetEvent<TickerSymbolSelectedEvent>().Subscribe(ShowNews);

 

eventAggregator.GetEvent<TickerSymbolSelectedEvent>().Subscribe(ShowNews, ThreadOption.UIThread);

ThreadOption有以下选项:

  • PublisherThread。使用此设置可在发布商的主题上接收活动。这是默认设置。
  • BackgroundThread。使用此设置在.NET Framework线程池线程上异步接收事件。
  • UIThread。使用此设置可在用户界面线程上接收事件。

 

发布者通过从EventAggregator检索事件并调用Publish方法来引发事件。例如,以下代码演示了如何发布TickerSymbolSelectedEvent

EventAggregator.GetEvent<TickerSymbolSelectedEvent>().Publish(“STOCK0”);

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

获取对事件聚合器服务的引用(事件聚合器服务实现Microsoft.Practices.Composite.Events.IEventAggregator接口,并负责创建和定位事件实例)。为此,您可以通过向类构造函数添加类型为IEventAggregator的参数来使用依赖项注入,如以下代码所示。如果您的类由容器实例化,则它将在构造时注入事件聚合器服务的实例。

public class Class1

{

      private IEventAggregator eventAggregator;

     public Class1(IEventAggregator eventAggregator)

     {

             this.eventAggregator = eventAggregator;

     }

 }

 

 

using Microsoft.Practices.Prism.Events;
        
private IEventAggregator TheEventAggregator { get; set; }
        
[ImportingConstructor]
public MyViewModel(IEventAggregator eventAggregator)
{
    TheEventAggregator = eventAggregator;
    //TODO: 
}        

然后可以进行事件的发布(Publish)和订阅(Subscribe):

TheEventAggregator.GetEvent<MarketPricesUpdatedEvent>().Publish(clonedPriceList);

上面代码中用到了一个自定义的Event: MarketPriceUpdatedEvent: (定义成你需要的数据类型就可以了,这里是IDictionary<string, decimal>)

public class MarketPricesUpdatedEvent : CompositePresentationEvent<IDictionary<string, decimal>>
{
}

事件聚合器用于集中管理事件的订阅(Subscribe)和处理(Handle),要使用事件聚合器,首先要理解:事件(event)本质上是一个类,如同本系列第一篇写到的老师(Teacher)和学生(Student)的例子

技术分享

接下来是实际应用,假设一个场景:吃饭。当出发了“开饭”的事件,所有订阅这个事件的人都会去“吃饭”:

“开饭”的事件:

public class MealDoneEvent:IEvent
{
    public string DishName { get; private set; }

    public MealDoneEvent(string dishName)
    {
        DishName = dishName;
    }
}

对应的“吃饭”处理器(Handler)

public class MealDoneEventHandler:IEventHandler<MealDoneEvent>
{
    private readonly string _name;

    public MealDoneEventHandler(string name)
    {
        _name = name;
    }

    #region Implementation of IEventHandler<in MealDoneEvent>

    public void Handler(MealDoneEvent @event)
    {
        Console.WriteLine($"{_name} is eating {@event.DishName}");
    }

    #endregion
}
static void Main(string[] args)
{
    var eventAggregator=new EventAggregator();

    eventAggregator.Subscribe(new MealDoneEventHandler("zhang san"));
    eventAggregator.Subscribe(new MealDoneEventHandler("li si"));
    eventAggregator.Subscribe(new MealDoneEventHandler("wang wu"));

    eventAggregator.Publish(new MealDoneEvent("dog shit"));

    Console.ReadKey();
}

http://www.bubuko.com/infodetail-1942067.html

 

在项目中添加EventAggregator类库,添加EventAggregatorRepository类和GetInputMessages类。

using Microsoft.Practices.Prism.PubSubEvents;
using Microsoft.Practices.Prism.Regions;
using System;
 
namespace EventAggregatorPratice
{
    public class EventAggregatorRepository
    {
        public EventAggregatorRepository()
        {
            eventAggregator = new EventAggregator();
        }
 
        public IEventAggregator eventAggregator;
        public static EventAggregatorRepository eventRepository = null;
 
        //单例,保持内存唯一实例
        public static EventAggregatorRepository GetInstance()
        {
            if (eventRepository == null)
            {
                eventRepository = new EventAggregatorRepository();
            }
            return eventRepository;
        }
    }
 
 
}

using Microsoft.Practices.Prism.PubSubEvents;
 
namespace EventAggregatorPratice
{
    public class GetInputMessages : PubSubEvent<string>
    {
 
    }
}

其中EventAggregatorRepository提供事件聚合实例,GetInputMessages为定义的事件类型。

 

https://blog.csdn.net/junjunjiao0911/article/details/84891787

 

https://blog.csdn.net/shishuwei111/article/details/81773372

 

[Import]
public IMessageSender MessageSender { get; set; }
class Program{
[ImportingConstructor]
public Program(IMessageSender messageSender)  {  } }
[Export(typeof(ShellViewModel))] 
public class ShellViewModel : HM_EMSTS.WorkStation.UICommon.NotifyBaseObject 
    { 
       public Action<string> OnStatusChanged;
 
        [ImportingConstructor] 
        public ShellViewModel(IEventAggregator eventAggregator) 
        { 
           //注册事件 
           if (eventAggregator == null) 
           { 
                throw new ArgumentNullException("eventAggregator"); 
            }
eventAggregator.GetEvent<HM_EMSTS.WorkStation.Infrastructure.Events.SystemStatusManagementEvent>().Subscribe(this.SystemStatusManagementEventHandler); 
        } 
       public void SystemStatusManagementEventHandler(string parameter) 
        { 
           if (parameter.IsNullOrEmpty()) 
           { 
               throw new ArgumentNullException("无法完成操作"); 
           }

          if (OnStatusChanged != null) 
               OnStatusChanged(parameter); 
       } 
  }

但是在ImportingConstructor的方式中,如果那个Export不存在,例如属于另外一个模块,而那个模块按需没有加载,这样在ImportingConstructor的时候就会报异常

image

image

image

 

image

image

image  

image

image

image

image

 

image

image

image

image

image

image

image

       image

 

https://www.cnblogs.com/joean/tag/wpf/

image

image

 

image

image

image

 

image

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值