Click here to Skip to main content
Click here to Skip to main content

Using MvvmLight with (XAML) Silverlight 4 or WPF

, 7 Apr 2011 CPOL
Rate this:
Please Sign up or sign in to vote.
How to get started with MVVMLight and XAML for unit testing.

Introduction

This tutorial will try and explain the advantages and the 'how to' of using MVVMLight within your XAML application so that you can produce code that is maintainable and more importantly testable.

Why Use the MVVM Pattern

The tight coupling of GUI to code-behind has, over the years, meant that testing the code-behind can be some what tricky. In that, how do you mimic the selected event in the GUI to call the bound event code - you can mimic the call to your event code, but how do you get the selected item from the combo (in the GUI) that doesn't exist, as you are not running the GUI but testing the methods that the GUI uses? What was needed was a loose coupling between the GUI and the code-behind, this is where Context classes come in - XAML (Silverlight or WPF) have a concept where a Silverlight page can have a (context) class associated with it for its events and also (more importantly) have setters and getters associated with the bindings to GUI controls. So when a property is updated by its setter, a call to your 'NotifyPropertyChanged' method in the class 'INotifyPropertyChanged' will trigger the rebinding to the control.

Install and Integrate MVVMLight Into Your Project

You can download and follow the instructions from Gala's web site here: http://www.galasoft.ch/mvvm/getstarted/.

Or:

Below is how to convert your project to an MVVMLight project after installing NUGet and running the MVVMLight installer:

SilverlightMvvmLight/Adding_Mvvmlight_to_your_project.jpg

Binding Scenarios

Commands

A command is basically a reference point for when an event happens in the GUI. The respective command (set in the XAML) will be triggered. In any MVVM design pattern, there is a RelyCommand that will determine if the command's associated method can be executed. Below, you can see that the button's command property has been bound to the 'ButtonCommand' command in code, in the context class - thus wiring up a (button click) event to this command in code - which in turn will call a method to act upon the command.

SilverlightMvvmLight/Bind_Command.jpg

Passing a Parameter to a Command

It is possible using a reference to the System.Windows.Interactivity class to pass parameters to the called command (again, there is a RelyCommand for this type of passing). Below the trigger is the 'SelectionChanged' event of the textbox, which will call the 'LstBoxChangedCommand' command with the parameter of the contents of the textbox.

SilverlightMvvmLight/BindingEventWithParameter.jpg

RelyCommand (including passing back parameter)

The RelyCommand will determine if the associated method of the command can be executed. There are a couple overrides for the RelyCommand, in that you can call the RelyCommand with a parameter, or not. Basically, there are two methods that can be called for each version (parameter or not). The only difference (other that expecting a parameter) is that you can fire a 'canExecute' method to determine if the command is valid to proceed processing. There is also a RelyCommand method that does not take a 'canExecute' and it will always fire the associated method of the command. For example, you might want the SelectedItemChanged event of a ComboBox to always fire, as you do not depend on any other controls\scenarios on the page. In the two images below, you can see the object browser view on the MVVMLight RelayCommand methods - the first one does not take parameters, but the second image shows the signature of the Relaycommand that does take a parameter.

SilverlightMvvmLight/RelayCommand_No_Paramater.jpg

SilverlightMvvmLight/RelayCommandWithParameters.jpg

Binding Setter Properties in XAML

Associate a binding with a setter property in the context class (that will be two way so that the changes can be posted back to the control - one way only means that the control tells the property that it has changed). In the image below, you can see that the SelectedItem is bound to the property 'SelectedTemplate' - which is a reference to a class in an ObservableCollection.

SilverlightMvvmLight/BindingProperty.jpg

MVVM NotifyPropertyChanged Method

With the above binding, and in two way mode, I can make a change to the property (maybe in the method associated with a command); for example, I have selected an item from a combobox - this triggers a command, the method associated with that command then sets a property that is bound to a label - that label with the use of the 'NotifyPropertyChanged' method will post the update back to the label.

Binding Event Properties in XAML

A developer will want to bind many GUI control events back to commands in the context class. This is possible using the 'System.Windows.Interactivity' class. We can bind any event in the comboxbox (for example) back to a command in the context class - to get say the selected item in the combobox, we would generally pass a parameter to the command. There is a caveat here, in that the SelectionChanged event is triggered before the SelectedItem binding can take place - so in this case, we would pass the SelectedItem to the command. Knowing that this scenario can happen, but also knowing that we can get around, this can only extend the use of the MVVM design pattern. Basically, an event cannot be triggered to a command in another class and actioned upon. Looking at this image again, you can see that I am binding to an event in the textbox - SelectionChanged. You can now bind to any event that a control has.

SilverlightMvvmLight/BindingEventWithParameter.jpg

Raising a Separate Command to Execute (Within Another Command Method)

The situation will arise that you need another event\command to fire after you have changed a property or to a separate event - this is possible by using the RaiseCanExecuteChanged method on the respective command that you wish to evaluate.

Sample Application

This application will need the MvvmLight DLLs added (as they made the size of the project after zipping over 11 MB). If you following the instructions in the introduction using NUGet, uou can add the DLLs easily.

The sample code basically validates what the user types in (the textbox) against the combobox to enable or disable the button (a valid entry is something that is not already in the combobox).

Unit Testing MVVM Code

In the downloadable project above, I created some tests that can be applied to the MVVM context class. Thus, I can mimic the 'KeyDown' event that will happen in the XAML in my test fixture.

SilverlightMvvmLight/Tests.jpg

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Bert O Neill
Architect
Ireland Ireland
No Biography provided

Comments and Discussions

 
GeneralSlightly misleading PinmvpPete O'Hanlon10-Mar-11 2:44 
GeneralRe: Slightly misleading PinmemberBert ONeill10-Mar-11 5:08 
GeneralRe: Slightly misleading PinmvpAspDotNetDev7-Apr-11 8:09 
GeneralNice Quick Start PinmemberPaul Selormey9-Mar-11 14:54 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web03 | 2.8.141022.2 | Last Updated 7 Apr 2011
Article Copyright 2011 by Bert O Neill
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid