Wednesday, February 12, 2014

A Primer For Creating Fluid Decoupled Apps using MVVM Light In Windows Phone 7 - (2) Inter-View Model Communication

Inter-View Model Communication Using MVVM Light Messenger


This is the second post in a series that will attempt to illustrate a way to decouple your application from the traditional code behind paradigm.


Sample code can be found here: https://bitbucket.org/jpmedina/mvvmcalculator

Note, the application implements a contrived calculator as such there is validation added that would, or might, be unnecessary using the correct input scope for the text boxes.


This code is free to use in any shape and form.  However, you cannot claim that you wrote the original although you can change it in any manor you see fit including using code in published applications to the Windows Phone Store.  I would appreciate any attribution.

This post uses the code in the sample project in the {View}xaml files where {View} is a variation on the Calculator.  The MainPage.xaml contains buttons that will load each of these pages, the behavior is identical.

Traditional View Model to View Model Communication

In the last post we discussed how traditional application logic is in the code behind for a given view.  We ended up learning that not only is this not always necessary but we can gain a bit of flexibility by relocating this logic to the View Model while using RelayCommand and RelayCommand<T> to glue the UI to this logic.  In this post we'll take a similar approach, first we'll discuss the traditional communication mechanim between different View Models in a system, this is possibly the same mechanism for other parts of the system, and a different approach that will give us a more flexibly approach for inter-view model communications.

A word of caution, pick the approach that best suits the application at hand.  Although this can be a great approach for many applications there are some drawbacks, which will be discussed later.  That being said, you can view the view model code in the MvvmCalculator.ViewModels project, specifically CalculatorViewModelTraditional.cs, CalculatorViewModelRefactored.cs and CalculatorViewModelAutomatic.cs.  Also if you were following the last post you'll notice some refactoring that has happened, the logic from CalculatorViewModel.cs (although this class has remained unchanged) has been extracted to a base class to make creating additional view models easier.

As an extension to the first post we're going to add persistence to our calculator application, although this is a bit contrived persistence is a common application attribute.  Let's assume a user wants to be able to backup their calculation results and actually rerun them.  It would be sad if you had to input all of your numerical analysis each time you reopened the application.  In order to do this we create a settings dialog that will open up when the settings icon is pressed on the application bar or menu item.  I chose to do this inline as using page navigation can add a bit of complexity.  The application bar will fire a command to our settings view model which will trigger a visibility value causing the dialog to open.  You can find the code for the settings view model in SettingsViewModel.cs, SettingsViewModelRefactored.cs and SettingsViewModelAutomatics.cs.

In order for us to save the calculations, I've chosen isolated storage for simplicity, the settings view model needs the calculations.  The traditional way to do this is to either create the dependency within the settings view model or what I've chosen here, inject an instance of the calculator view model into the settings view model.  Ideally we would use an interface in order to allow for testing, but each view model contains few dependency and testing isn't our goal in this series.  Here's the constructor:

public SettingsViewModel(CalculatorViewModelTraditional calculatorViewModel)
{
    _calculatorViewModel = calculatorViewModel;

    this.ShowDialogVisibility = Visibility.Collapsed;

    if(!Settings.Contains("Settings"))
    {
        InternalSaveSettingsHandler();
    }
    else
    {
        InternalRestoreSettingsHandler();
    }
}

This constructor sets the visibility of the settings dialog to "Collapsed" so that it doesn't show unless the user requests it.  If there are no settings saved it creates the default settings otherwise it will reload them.  The dialog simply contains a toggle button and a save/reload button (the toggle button doesn't do anything).  Note how this is a coupling between the SettingsViewModel and the CalculatorViewModel.  Any changes that are made to the latter require updates in the former.  Although this is a small application as you can imagine if we expand it to include more functionality this might become a maintenance nightmare.  However, this is very common.  Even if we abstracted the CalculatorViewModel with some other placeholder, for example a model, we would still be tied to the functionality.  If this is common and the more traditional approach, as it is in ASP.NET MVC, WebAPI or WCF, what approach can we take to reduce this coupling?

Inter-View Model Communication Via Messenger


Of course this is a leading question as we already have an approach.  You wouldn't be reading part 2 if you didn't have an idea of what it was.  That's right we can use MVVM Light's Messenger, or rather messaging, mechanism.  However, we can't just throw that into the mix, we need to come up with a model, that will be a good representation of what's going to be saved in isolated storage.  You can find the SavedSettingsModel in MvvmCalculator.Core project under Models.   That's the first part, secondly we need a message to represent saving a model, a la MOA (Message Oriented Architecture).  Messages should represent actions taken on the data in the message, for example if you want to save settings, a saved settings message should be sent.  You can find these messages, also in the MvvmCalculator.Core project but this time under Messages.  I've created a MessageBase class that contains common elements that are used for messages.  Now that we have our model to save and the messages that represent actions on the model what comes next? As is common once you have your building blocks you need glue to hold them together.  That glue is the MVVM Messenger class.

Take a look at SettingsViewModelBase.cs, particularly the constructor, this contains the common code across all SettingsViewModels.  Notice this method being called:


private void CreateRegistrations()
{
    Messenger.Default.Register<SettingsRestoredMessage>(this, this.SettingsRestoredHandler);
    Messenger.Default.Register<SettingsSavedMessage>(this, this.SettingsSavedHandler);
}

Here we're using the default messenger, you can define others but the default make things simpler.  Each line is a registration that tells the messenger, which is essentially an in memory service bus,  that for each of the message types call the method defined on "this", and pass the message to it.  You can also use a statement lambda if you don't want to define a separate function:

Messenger.Default.Register<SettingsRestoredMessage>(
    this,
    m =>
    {
        //Handle message here,    
    }
);

Both ways can produce the same result although if you have a lot of logic, the method makes it easier to work with.  Great now the SettingsViewModel doesn't need to care about the CalculatorViewModel, in fact you can look at SettingsViewModelRefactored and the SettingsViewModelBase to confirm that is the case.  However, that's only half of the story, we need to be able to tell other subscribers, those subscribing to SaveSettingsMessage, that there are settings to save.  How is that done?  Here's how (in SettingsViewModelBase):

protected virtual void SaveSettingsHandler()
{
    Messenger.Default.Send(
        new SaveSettingsMessage(
            new SavedSettingsModel
            {
                VibrateOn = this.VibrateOn
            }));
}

Here the SettingsViewModel tells the messenger to notify observers about a SaveSettingsMessage (notice here we use the SavedSettingsModel to transmit data).  The Messenger class with call each method for each observer that is registered to be notified about SavedSettingsMessage's.  Note, the virtual behavior is used for SettingsViewModelAutomatic.  If you look at the corresponding CalculatorViewModelRefactored you'll notice that it too create a registration for SaveSettingsMessage.  That's because it's the only one that should know about calculations and if it wants them to be saved it needs to add them to the message and pass it along.  In this case we have to send a different message, SavingSettingsMessage, in order to avoid an infinite loop.

One last piece that needs to be mentioned.  The behavior for the saving is actually in the SettingsModel.  This will be familiar to those using MVC (Model-View-Controller), the Model is the one that knows how to interact with the data, saving restoring, etc.  This is another way we can decouple our persistence mechanism from other parts of the system.  If we decide that IsolatedStorage needs to be swapped out or supplemented, via SkyDrive, GoogleDrive, SQLCE or other, than we only have one place to change it and the SettingsViewModel and CalculatorViewModel benefit without any code changes (unless of course you change the message by removing or renaming properties).  The SettingsModel sends out additional messages when the settings are saved and when they are being restored.  This is truly cross view model and even model communication without each component having to be directly aware of each other.  The last view model pair, SettingsViewModelAutomatic and CalculatorViewModelAutomatic, illustrate that rather than wait on the user to ask for persistence you can perform it automatically.  This way you can support Tomb-Stoning without having to use event handlers in the UI.

I won't go over all of the code as I'm hoping it's clear.  However, feel free to send me an email or add a comment to the blog.  However, I need to go over some caveats to using this approach.

Messenger This Messenger That, And When It's Not

For a large number of scenarios you'll have no issues with using messages via Messenger, but there will be times when you might find that a handler doesn't get called, or sometimes it gets called to often.  Here's a list of issues and possible reason:

Handlers are not being called but are being registered

You'll run into to this if the class that has the handler registration is not in memory before the Messenger goes through the list of observers.  This is because of a temporal message workflow.  It's advisable that you document you workflows, something that will be discussed in a continuing blog post, so that you can keep track of what message needs to happen when.  Also if necessary and you're using an IOC container you can make a call to GetAllInstances, GetInstance or a relevant Get/Resolve method in order to guarantee that the component is initialized.

Handlers are being called multiple times


As its advisable that you document your message workflows so you can determine if this is the correct behavior.  If you register the same message in the same class with the same registration, it will be register again and hence called that many times.  You can either set your instance to be a singleton, if using an IOC container, or create a private static bool flag value and check before registering more than once.  Consider using the Unregister method of Messenger if you no longer want or need to receive events.

Messages That Interact With the Binding Are Slow

Are far as I can tell the Messenger is synchronous so if you have long running message interactions your best best is to find a way to make the asynchronous, this will depend on the platform, Windows Phone 7 vs 8 and Windows 8 Store apps.

To Message Or Not To Message That Is the Question

To wrap up, you can gain a loosely coupled application by forgoing the traditional view model coupling or IOC injection pattern and instead using the MOA pattern via MVVM Light's Messenger class.  This approach is simple and effective for most approaches but you must be careful and evaluate the needs of your application.  You must be aware that using messaging can introduce temporal workflows where one view model must be "alive" or in memory before it will receive or send messages.  Also you have to be careful to only register handlers only as often as needed.  Given a few of the issues with messaging it is my opinion that for most cases the benefits (decoupling, flexibility, testing, maintenance, etc) greatly outweigh any negatives.

In the next post I hope to show a more advanced messaging workflow by building on the code we currently have.  Until then feel free to comment as well as pull the code down and run it.

Thursday, January 30, 2014

A Primer For Creating Fluid Decoupled Apps using MVVM Light In Windows Phone 7 - (1) Using RelayCommand

Using RelayCommand and RelayCommand<T> instead of using logic in the XAML code behind


This is the first in a series of posts that will attempt to illustrate a way to decouple your application from the traditional code behind paradigm.


Sample code can be found here: https://bitbucket.org/jpmedina/mvvmcalculator

Note, the application implements a contrived calculator as such there is validation added that would, or might, be unnecessary using the correct input scope for the text boxes.


This code is free to use in any shape and form.  However, you cannot claim that you wrote the original although you can change it in any manor you see fit including using code in published applications to the Windows Phone Store.  I would appreciate any attribution.

This post uses the code in the sample project in the {View}xaml files where {View} is a variation on the Calculator.  The MainPage.xaml contains buttons that will load each of these pages, the behavior is identical.  [Update: The code has been refactored for the second series, although the UI is nearly identical]


Traditional Application Logic Is In the Code-Behind

Many developers have experience with WinForms, WebForms, WPF, Windows Services or ASP.NET MVC and recognize the traditional mechanism for working with business logic is by having a UI editor attached to a code-behind file.  Windows Phone applications are no different.  This can be seen in the default application where MainPage.xaml contains the UI (XAML declarations) and MainPage.xaml.cs or The Code-behind which houses the C# code.

Often times an application's view has a Button, or a ListBox item that needs to do something when clicked, pressed, scrolled or when another UI event happens.  The first and most common mechanism, in WP7 and WP8 it's the default experience, is to name the element and create a button event in the code behind for example (referring to the sample application in (CalculatorTraditional.xaml.cs):


private void OperationAddButton_Click(object sender, RoutedEventArgs e)
{
    this.CalculatorResult.Text =
        this.CalculatedResults(
            (l, r) => l.Number + r.Number);
}
 
private void OperationSubtractButton_Click(object sender, RoutedEventArgs e)
{
    this.CalculatorResult.Text =
        this.CalculatedResults(
            (l, r) => l.Number - r.Number);
}
 
private void OperationMultiplyButton_Click(object sender, RoutedEventArgs e)
{
     this.CalculatorResult.Text =
        this.CalculatedResults(
            (l, r) => l.Number * r.Number);
}
 
private void OperationDivideButton_Click(object sender, RoutedEventArgs e)
{
    this.CalculatorResult.Text =
        this.CalculatedResults(
            (l, r) => l.Number / r.Number);
}


Notice that these methods represent event handlers that respond to click events on the named element.  For example, OperationAddButton_Click, represents the event handler for the Button.Click event of the OperationAddButton.

This is not a lot of code and at first glance it easier to keep it in the view’s code behind.  That’s a great assumption, if the code you write is concise, specific and not meant to be reused across different views or applications it not only easier, but faster to keep most if not all of the event handlers in the view.  However, once your application has graduated from simple to something more complex, having application logic in your view tends to make updating your application harder while increasing the time it takes to debug and release new features.

Using RelayCommand


That’s great but how do I do that? How is it possible to remove the logic while at the same time not cluttering your code with UI elements and references?  While a worthwhile goal often times it is necessary to include some dependency on UI elements like Color and TextBox (in order to access specific properties that cannot be intercepted).  However, the majority of the logic can be UI agnostic.  One mechanism is by using the MVVM pattern and more specifically the RelayCommand and RelayCommand<T> in the MVVM Lite Toolkit: http://mvvmlight.codeplex.com/.

Get ready, here comes the trick, wait for it, wait, Data Binding!


In the CalculatorNoCodeBehind.xaml view you can see that the structure is nearly identical to the first sample.  The major points are the binding syntax and this:




1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
<Button x:Name="OperationDivideButton"
        Foreground="{StaticResource PhoneAccentBrush}" 
        FontSize="48" 
        Width="100" Height="100" 
        Padding="0" Margin="0"
        Content="/">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Click">
            <mvvmLite:EventToCommand x:Name="OperationDivisionCommand" 
                                     Command="{Binding OperationDivisionCommand}"/>
        </i:EventTrigger>
    </i:Interaction.Triggers>
</Button>

USING INTERACTION TRIGGER




1
2
3
4
<Button Command="{Binding ElementName=ResultClearButton, Path=DataContext.OperationReloadCommand}"
                          CommandParameter="{Binding}" 
        ContentTemplate="{StaticResource ResultListButtonItemTemplate}">
</Button>

USING COMMAND DIRECTLY ON BUTTON



The obvious part, if you've used data binding before is binding the OperationDivisionCommand to the interaction trigger.  The not so obvious part is the <Interaction.Triggers> element and the Command binding directly on the button (in newer release of MVVM Light).  The interaction trigger and Command binding are the little gems provided by the MVVM Light toolkit in order to allow interception of UI events.  This is the glue that allows us to move the logic that was contained in the code behind in the first sample to the CalculatorViewModel in the second one.  This is the simpler of the two forms, it allows our user defined Action (in the C# sense) to be called, and optionally a Func that computes whether or not to execute the Action, for the given UI event.  Here’s the code for the command creation, in the CalculatorViewModel constructor, for the RelayCommand shown:


this.OperationDivisionCommand = new RelayCommand(this.OperationDivisionHandler);

Alternatively we could have initialized the RelayCommand like this:

this.OperationDivisionCommand = new RelayCommand(() => this.OperationDivisionHandler());


When the calculator’s division button is clicked the event is intercepted and our OperationDivisionHandler method is called.  The major advantage here is that the CalculatorViewModel is unaware of who triggered the event and who is responding to it.  This is in contrast to the original code with had to be aware of the TextBox directly.  Also the code and XAML can now be reused without a lot of refactoring for other pages and applications.

Using RelayCommand<T>


RelayCommand is excellent for triggering actions based on button presses that require no information from the UI to be sent to the business logic in the ViewModel.  Although that’s a common scenario it’s not enough to enable some advanced applications.  So then how does the UI send information to the ViewModel, or rather how does the ViewModel become aware of UI information?  That is where RelayCommand<T> comes into play.

In CalculatorWithTypedRelayCommand.xaml, which is another view that can be accessed from the main page, you’ll notice that the previous TextBlock named “CalculatorResult” has been refactored to be a ListBox named “CalculatorResult” with an ItemTemplate whose DataTemplate “ResultListDataTemplate” can be found in /Resources/DataTemplates.xaml.  The ListBox DataTemplate consists of two pieces, a Button and the Buttons DataTemplate “ResultListButtonItemTemplate”.  Each item in the list box will be a button that shows the left value, the operand and the right value horizontally in a StackPanel.  The button definition looks like this:


1
2
3
4
<Button Command="{Binding ElementName=ResultClearButton, Path=DataContext.OperationReloadCommand}"
        CommandParameter="{Binding}" 
        ContentTemplate="{StaticResource ResultListButtonItemTemplate}">
</Button>


Notice the same “Command” binding but this time there are a couple of additions.  First the location to the Command, in this case a RelayCommand<T>, has two be specified since the item being bound is not the ViewModel but each item from the list box.  The location is on an element named “ResultClearButton” on its DataContext with the command of OperationReloadCommand.  Second, the additional “ComandParameter” element with the value of “{Binding}”.  This tells MVVM Light that the bound element needs to be used as the type for the RelayCommand<T>.  The command initialization looks like this, in CalculatorViewModelTypedRelayCommand.cs:


this.OperationReloadCommand = new RelayCommand<CalculationResult>(this.OperationReloadHandler);


A point of interest is that the RelayCommand<T> is using CalculationResult, which is a class defined within the ViewModel class, as the parameter of OperationReloadHandler:


public void OperationReloadHandler(CalculationResult oldResult)
{
    this.LeftNumber = oldResult.Left.ToString();
    this.RightNumber = oldResult.Right.ToString();
}


This method simple reloads the left and right values from the calculation that was just clicked in order to recalculate it.  A bit contrived but it allows us to see how we can get information for the ViewModel to the UI and back to the ViewModel with no code behind whatsoever.  What happens if we need to access something that is not a bound data item, for example, what if we wanted to make it easier for the user to change their calculation without having to highlight the entire number?  What about adding a select all text method?  This is arguably one case were we can us a UI element in the ViewModel (there are other ways but as long as you keep the usages neat and tidy as well as isolated this is an easy way to do it.  Let’s add another RelayCommand but this time rather than send a data item let’s send the UI element that triggered the event (GotFocus):

The command:


this.CalculationTextBoxGotFocusCommand = 
    new RelayCommand<RoutedEventArgs>(this.CalculationTextBoxGotFocus);


The handler:


private void CalculationTextBoxGotFocus(RoutedEventArgs e)
{
    var textbox = e.OriginalSource as TextBox;

    if( textbox == null )
    {
        return;
    }

    textbox.SelectAll();
}


And of course the glue, the TextBox command binding (the left number and right are analogous):



1
2
3
4
5
6
7
8
9
<TextBlock FontSize="24" Text="Left Number">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="GotFocus">
            <mvvmLite:EventToCommand x:Name="LeftNumberFocusCommand"
                                     Command="{Binding CalculationTextBoxGotFocusCommand}"
                                     PassEventArgsToCommand="True" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</TextBlock>


As far as I am aware there isn’t an easy way to do this without an interaction trigger, but this is a small price to pay for this flexibility.  Some explanations are in order.  We’ve seen most of the before, there are three elements necessary when using Relay Commands (both generic and non-generic).  First, we need a command defined on our ViewModel, second we need a handler that will take care of the intercepted event.  Lastly we need the binding defined in our XAML that glues the whole thing together.  We have those three pieces here, the “CalculationTextBoxGotFocusCommand” command, the “CalculationTextBoxGotFocus” handler (this is my term as it Handles the event) and the interaction trigger “LeftNumberFocusCommand” and it corresponding “RightNumberFocusCommand” one.  There one difference here that was not in the last RelayCommand<T> we used, the “PasEventArgsToCommand=True” attribute.  Hopefull this is simple, the event, in this case a RoutedEventArgs parameter, is passed to our handler.  And that’s it.  We can access the UI element from this args to handle interactions that are hard to accomplish with data only RelayCommands.

And with that this is the end of the first post. Hopefully there has been enough detail to show you not only how to use the MVVM Light toolkits two RelayCommand mechanism but also given you a good reason to start thinking about using ViewModel as the business processors rather than just the traditional code behind. The next post will detail ViewModel to ViewModel communication using the traditional mechanism, IOC and dependency injection and what I believe is a looser approach, Messaging.

Friday, January 3, 2014

A Primer For Creating Fluid Decoupled Apps using MVVM Light In Windows Phone 7

    I've written a couple of apps and am current working on another one and want to share my experience with how I using the Messenger mechanism in MVVM Light in order to decouple my application from uncessary logic.  I'm hoping to show lots of code but this might take a while to get online.  Here's a list of preliminary topics that I want to cover:

1.  Using RelayCommand?
2.  Inter-View Model Communication.
3.  Creating Workflows using messaging.

That seems like a light load but getting to a point where understanding what is necessary and why can be in depth.  Hopefully this will become more organized when I get to writing about each topic.