I'm using Prism's EventAggregator for loosely coupled communication between my module's ViewModels. I have have several properties (e.g. FirstName, LastName) in ViewModelA which need to update properties in ViewModelB when their values change. My current solution involves:
ViewModelA publishes an Event with the new value for FirstName as the payload:
public string FirstName
{
get {return firstName;}
set
{
this.firstName = value;
eventAggregator.GetEvent<PatientDetailsEvent>().Publish(firstName);
}
}
ViewModelB is subscribed to the Event and changes its FirstName property accordingly:
public PatientBannerViewModel(IEventAggregator eventAggregator)
{
this.eventAggregator = eventAggregator;
eventAggregator.GetEvent<PatientDetailsEvent>().Subscribe(UpdateBanner, ThreadOption.UIThread);
}
public void UpdateBanner(string firstName)
{
this.FirstName = firstName;
}
This works fine for a single property. It doesn't work for multiple, different properties because ViewModelB has no idea what property has changed on ViewModelA . ViewModelB knows what the new value is, but it doesn't know which of its properties to update.
I could create separate Events for each property but this seems repetitive. It seems cleaner to just use one Event. Ideally, when publishing the Event, ViewModelA should tell ViewModelB which property has changed. How can I do this?
Sorry, I found the answer to my question in this post. This blog post by Rachel Lim is also helpful.
What we need is for ViewModelA (the publisher) to tell ViewModelB (the subscriber) two pieces of information:
We need to communicate 2 pieces of information (i.e. properties) but Prism's EventAggregator takes only one parameter, the payload
. This is the problem.
To pass multiple pieces of information (properties) via the EventAggregator you can publish an instance of a class which defines these properties as the EventAggregator's payload
. I called this class PatientDetailsEventParameters
and it defines two properties:
public class PatientDetailsEventParameters
{
public string PatientProperty { get; set; }
public string Value { get; set; }
}
I created this class in an Infrastructure assembly (the same place where I define my Events) which all my other assemblies have a reference to.
You can then publish an instance of this class as the payload (instead of a string which holds only 1 value). This allows for multiple parameters to be passed into the payload.
public string FirstName
{
get
{
return firstName;
}
set
{
this.firstName = value;
eventAggregator.GetEvent<PatientDetailsEvent>().Publish(new PatientDetailsEventParameters() {Value = firstName, PatientProperty = "firstName"});
}
}
You can see here that a new instance of my PatientDetailsEventParameters
is created when the PatientDetailsEvent
is published. The two properties Value
and PatientProperty
are also set. PatientProperty
is a string which tells ViewModelB (i.e. the subscriber) what property has changed. Value
is the new value of the property that has changed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With