The main advantage for using an event aggregator to communicate between user-controls is, it removes the tight coupling between a publisher and a subscriber, by which a publisher/subscriber can evolve independently. Pre-requisites for understanding this blog post is to have a bit understanding of Event Aggregator.
Live Demo : Event Aggregator Sample
Source Code: At the end of this post :).
In this post i will explain how two user-controls can pass messages between them using event aggregator, consider a simple chat scenario where one user types-in some message and sends to to another user and vice-versa. My Visual Studio Solution looks as shown below, things to observe are
- Microsoft Practices Composite dll's which are required for implementing the event aggregation
- EventAggregator.cs which implements the interface IEventAggregator. (Note: will share the enitre source code at the end of this blog post :) )
- "Kranthi.xaml" and "Kiran.xaml", two user controls which communicate using event aggregator.
Both the user controls have same functionality to implement. Lets see how the "Kranthi.xaml" user-control UI is likely to be, it contains following:
- Text Box, where user enters message to publish.
- Button, used to publish the entered message in TextBox.
- ListBox, to display the received messages from the subscribed event.
So now i am defining two events to communicate
- MessageToKiran event is published by "Kranthi.xaml" and is subscribed by "Kiran.xaml".
- MessageToKranthi event is published by "Kiran.xaml" and is subscribed by "Kranthi.xaml".
namespace EventAggregationSample { public class MessageToKranthi : PresentationEvent<string> { } public class MessageToKiran : PresentationEvent<string> { } }Subscribing to Event:
Before subscribing or publishing a message, we need to instantiate EventAggregator and Subscribe to event as shown below
IEventAggregator Aggregator { get; set; } //Constructor public Kranthi() { InitializeComponent(); Aggregator = new EventAggregator(); Aggregator.Subscribe<MessageToKranthi, string>(OnMessageToKiran); } public void OnMessageToKiran(PresentationEvent<string> e) { ListBoxItem item = new ListBoxItem(); item.Content = e.Payload; lbMessages.Items.Add(item); }In the Constructor, I've initialized the Aggregator and subscribed to the event MessageToKranthi, which has a payload of type string(which is our message). Whenever any user-control publishes MessageToKranthi event then "OnMessageToKiran" code gets executed.
Publishing an Event:
We can use event aggregator to send message for all subscribers of that event as below
Aggregator.SendMessage<MessageToKiran, string>( new MessageToKiran { Payload = tbMessage.Text } );The above code publishes "MessageToKiran" event with the payload of the user entered text, this text is passed as payload to all the subscribers for this event.
To Complete the Communication, two user-controls should perform the following activities
- Kranthi.xaml - Publish the event "MessageToKiran" and Subscribe for the event "MessageToKranthi"
- Kiran.xaml - Publish the event "MessageToKranthi" and Subscribe for the event "MessageToKiran"