It’s often necessary to “inform” other areas of an application of changes that have occurred. This can be achieved through Messaging. In the previous tutorial we created a Settings page and made the TranslationDirection Configurable. It would be nice if the Main View Model knew about our new Translation Direction setting, let’s look at how we can achieve this.
By the end of this tutorial we should have implemented a SettingsChangedMessage, subscribed to it from our MainViewModel and Published it from our SettingsViewModel.
We’ll need a Message object to pass around. Let’s start by creating one. Create a new Folder called Messaging and a new class called SettingsChangedMessage.
Currently, only the Translation Direction is configurable, add a TranslationDirection Property to the new class, and a constructor to set it’s value.
public class SettingsChangedMessage
public TranslationDirection TranslationDirection
public SettingsChangedMessage(TranslationDirection translationDirection)
TranslationDirection = translationDirection;
As you can see, this class is really simple. It’s not inheriting from anything clever, it’s a simple POCO. The type SettingsChangedMessage, will act as the identifier for the underlying message routing, with the Properties on it being what the Subscriber can read from, note the public get and the private set.
In the previous post, we kept our Translation Direction setting DRY by creating a private SetTranslationDirection method, this is also where we can hook in to publish from.
The MVVM Light ViewModelBase our ViewModels inherit from contains a MessengerInstance property we can use to publish new messages on to our Application’s Message bus. Let’s look at adding that in.
private void SetTranslationDirection(TranslationDirection translationDirection)
_morseCoderSettings.Direction = translationDirection;
CurrentTranslationDirection = _morseCoderSettings.Direction;
var settingsChangedMessage = new SettingsChangedMessage(CurrentTranslationDirection);
What’s going on here?
- Usual Setting of the Current Translation Direction as before;
- Creating a new Message object, being supplied with our new CurrentTranslationDirection.
- Using the MessengerInstance to send our message to any interested subscribers (currently none!).
Our message will currently be disappearing into the void, so let’s look at adding a subscriber.
Message type subscription happens within the ViewModel Constructor of the interested party, in our case we’ll need to update the Constructor of our MainViewModel, and provide it with a message handler method.
Our method need to take an object of type SettingsChangedMessage, let’s look at creating a shell which we can update later:
private void SettingsChangedMessageHandler(SettingsChangedMessage settingsChangedMessage)
We can now add in our Registration to the Constructor:
We’ve specified that the object to handle our message will be our MainViewModel (this), and the Method on it will be the SettingsChangedMessageHandler we just specified.
With a small amount of refactoring of the ViewModel we can update our SettingsChangedMessageHandler to:
- check that the Translation Direction isn’t the same as the current;
- set the new Direction from the message;
- Configure the translator accordingly (abstracting a method from the constructor);
- Set our existing Input to our Translation, swapping the translation direction, which will cause the Translation to be re-evaluated.
if (settingsChangedMessage.TranslationDirection != Direction)
Direction = settingsChangedMessage.TranslationDirection;
Input = Translation;
Our MainViewModel now reacts to change on the SettingsViewModel.
For more information on the nature of the refactoring check out the Morse Coder Github Repository.
Where are we?
- We created a Message object to pass around;
- We instantiated and published our new object;
- We subscribed to and handled our new object;
- We can now pass messages between ViewModels.
Where are we heading?
- making the app User Experience (UX) more usable;
- adding some more functionality to our About Page;
- methods of serialising POCOs to Application Settings.