Introduction
While playing with PRISM 4, I loved the logic of regions. But in MVVM vs. PRISM standards, you have to obey some rules. To fire a simple event from one region to another, there're lots of choices out there. One of them is Event Aggregator.
For my tiny trigger need, I decided to create easy to use class, based on Event Aggregator.
These points are important for me for the class:
- This class should be very easy to use.
- While writing the code, I want very simple line of code; trigger event from a region/view and catch it from another region/view.
- And also, this class should not override the logic structure of MVVM and/or PRISM.
I hope you like this article and will be useful to you.
Background
To understand this article, you should have knowledge about WPF, MVVM and PRISM.
I also strongly recommend you to give it a time to read about PRISM documentation where you can access from:
Using the code
Note: I used NuGet Packages to reference necessary assemblies in solution.
Event Aggregator Class
The EventAggregator
class is based on CompositePresentationEvent
.
In base, we'll be using a global event handler. But this class will handle initialization process on itself. Only thing you'll do is to call its properties in your code.
Let's think about a little project. In this project, we have two regions. In first one there's a list box containing file names which read from local disc. We want to see the name of the file on second region while we click on list box.
First we'll create our event class. Let's name it to FileSelectedGlobalEvent
. This class will not be static. But EventAggregator
in that class will be static.
class FileSelectedGlobalEvent : CompositePresentationEvent<string>
{
private static readonly EventAggregator _eventAggregator;
private static readonly FileSelectedGlobalEvent _event;
static FileSelectedGlobalEvent()
{
_eventAggregator = new EventAggregator();
_event = _eventAggregator.GetEvent<FileSelectedGlobalEvent>();
}
public static FileSelectedGlobalEvent Instance
{
get { return _event; }
}
}
First, we're creating a static instance of EventAggregator
. Then, by using EventAggregator
's GetEvent
method, we're creating CompositePresentationEvent
from same class, which is also static. Now we have FileSelectedGlobalEvent
. By a static property (let's name it "Instance") we can access events, without any create process in out code.
Note that, because we want to transfer file name to other region, we create the class with CompositePresentationEvent<string>
. You can use your own class here.
Publisher Code
Let's assume that we have a view model, called FileListViewModel
.
The code in XAML is:
<ListBox ItemsSource="{Binding FileList}" SelectedItem="{Binding SelectedFile, Mode=TwoWay}" />
The ItemsSource
property is bound to FileList
and the SelectedItem
property is bound to SelectedFile
property with two way. So, when user selects from list, SelectedFile
property's set will execute.
Let's see whats going on in SelectedFile
property:
public string SelectedFile
{
get { return _selectedFile; }
set
{
if (value == _selectedFile)
return;
_selectedFile = value;
RaisePropertyChanged(() => SelectedFile);
FileSelectedGlobalEvent.Instance.Publish(value);
}
}
As you see, we only use single line of code to trigger event:
FileSelectedGlobalEvent.Instance.Publish(value);
Subscriber Code
Let's look at the subscriber code. Subscription is made in construction of the view model class.
class FileInfoViewModel : NotificationObject
{
public FileInfoViewModel()
{
FileSelectedGlobalEvent.Instance.Subscribe(ProcessFile);
}
private void ProcessFile(string fileName)
{
var fileInfo = new FileInfo(Path.Combine(GlobalVariables.RootPath, fileName));
FileName = fileName;
CreatedDate = fileInfo.CreationTime;
UpdatedDate = fileInfo.LastWriteTime;
}
}
In construction, we call Subscribe
method and delegate it to a method.
FileSelectedGlobalEvent.Instance.Subscribe(ProcessFile);
Because of we used CompositePresentationEvent
with string, ProcessFile
takes string argument. You can use your own class here.
History
This is the first published version.