MVVM (Model-View-ViewModel) is a software architectural pattern, mostly used in WPF and other xaml based projects. It separates the UI design related codes from the back-end logic of the project. In this article, we give a short review on MVVM and then move on to create a WPF project using MVVM Light toolkit which includes project creation, data bindings, navigation and messaging.
- Why MVVM
- MVVM structure
- MVVM Light for visual studio 2017
- Data Service
- Login page example
- Login View-model
- Navigation Service
MVVM (Model view view-model) is a development standard, derived from MVC model for XAML based software development.
With MVVM, we eliminate the need for XAML’s code-behind. The code-behind is hard to maintain, hard to test, tightly coupled and makes our code very complicated. With MVVM, we write code that’s easy to test and also very flexible to change.
MVVM contains 3 main modules.
This module, contains the models that we’re going to use in our project
This module, contains the XAML code and their code-behind
This module, contains the handler and data-binding we’re going to use to control our Views, using our Models.
We call our handling of data and commands, data binding. Since we won’t be using code-behind, we need a way to pass data to our Views, and also handle actions that are received from view (Such as button clicks). With data binding, we can bind an object to our view and make it do the work. With this design, we can later simply test our function by calling it from the test, and it will have nothing to do with the XAML structure. Also, whenever we move a XAML object from one file to another, it can still find the command because it’s not just looking for them in the code-behind.
Using MVVM, causes navigation to become a little bit harder. With code-behind, we simply just created a new instance of the next page’s code-behind and ran it. But here, since the Model-view doesn’t have a context like code-behind, it wouldn’t know how to navigate. So, we need to implement a navigation-service to do our navigation for us.
With MVVM, we can also have something called design-time data. This will allow us to add some dummy data to our views to make the UI design easier. Say we have a list-view that we want to populate dynamically. Tools such as visual-studio UI design or blend, won’t be able to populate the list-view without running the code.
We use a Boolean value to determine whether we’re in design-time or not. If so, we would use a different Model than we normally would which populates our object with dummy data. That way, when we’re using tools like blend, we will always have the required data and that would make the designer’s job much easier.
Now let’s do some coding…
MVVM Light for visual studio 2017
For our test project, we’ll be using MVVM Light. MVVM Light is a set of tools that will help us implement MVVM model much easier. You can install this suite using visual studio market place.
Creating the project
In visual studio, go to Create new project… and choose MVVM Light. It will Create the following structure. It has created 4 Folders.
This is for our design-time models
This is for our normal models
I’m assuming this contains styles
This is for our view-models
I’ll also add another folder Views for our XAML files. But later. First, let’s go through the code a little bit.
ViewModelLocator, is a class defined in
ViewModelLocator.cs file. This class, is the base class for our view-models. All other view-models must be registered here. (This is the design that mvvm light is using. It’s not defined in the mvvm standard and therefore, you are not obligated to use it.)
In this class, we have registered a Data Service, and View-model.
As you can see, we’re using
ViewModelBase.IsInDesignModeStatic to determine if we’re in design mode or not. It we are, we use a different model that has the dummy data.
We have also registered the
MainViewModel which contains our data bindings for
To connect to data, we use DataServices.
It derives from
IDataService interface and it only contains a
GetData function to return the only data it has.
DataItem is just a simple class that contains a property
It’s also worth taking a look at DesignDataService:
What you see here, is almost exactly what you had with
DataService, but in a real case scenario, these two would be different.
Last but not least, Let’s take a look at our
MainViewModel class. the View-model for our
WelcomTitle property is the field that will be bound to a xaml object and it’s get and set functions will get private field
_welcomeTitle and set it’s data respectively.
As you can see, the constructor for this class is being called with an
IDataService parameter (Do a search for Dependency Injection if you don’t know how that works). We’ll set our
WelcomeTitle from the data we get from
The xaml file, sets the
DataContext to our Main class. Take note, this Main property, is not exactly the class name. It’s the field we previously had in the
ViewModelLocator class which was of the type
WelcomeTitle (which is being called by the
TextBlock) binds to the field in the
If you run the project, this is what you’ll see:
Alright, up to now, we overviewed the project that was given to us by MVVNLight. But now, let’s add some stuff ourselves. For this section, i’m going to add login page.
Login page example
For the login page, we need the following:
- Login xaml page
We also need a navigation service to handle our navigation. Let’s get to it then:
Login xaml page
Add a new WPF Window and call it
This is the full code of the file:
DataContext is bound to the Login field in the
ViewModelLocator class. Just like what we had with Main. (Add that yourself) Both
textboxes are bound to a field in the
LoginViewModel class that i’ll show you in a minute. The Button is also bound to a
RelayCommand field in that class. As you see, we can pass Parameters to the command as form of a
CommandParameter. Here, since we had 2 parameters, we used a
MultiBinding, needs a Converter to be able to convert the elements into a class. The Converter is defined a little higher, inside Grid.Resources element. the
LoginConverter object, is defined in the
LoginViewModel (Probably should be in a better place)
Here’s the full code for
LoginViewModel class. Also, we included the
LoginConverter classes in the same file (Because of laziness. don’t do that in real projects):
LoginCommand is of type
RelayCommand that takes
LoginInput as parameter.
InputParams is of type
LoginInput, and the
textboxes are bound to this object. Defining
RelayCommand, we need to pass to parameter. The command
funcition (here: login), and a
CanExecute function (We simply set that to true for now). Also, the login function, just shows a dialog that says login works. We want to change that so that it would navigate to the
Please do run the project and test before moving on to the next chapter. Oh also, don’t forget to change the default page in the App.xaml file from
Now that we have our login page working, let’s create a navigation service to be able to navigate from login page, to the Main page. Alright, first off, we have to change some things. We should change
MainWindow to contain a navigator item and from now on,
MainWindow won’t be a real page of the project. just the container for other pages. So change it this way:
important: Don’t forget to keep the previous data and move it to a new page. let’s call the new page ‘MainPage.xaml’
It only contains a
Frame component, which as default source, we set the
LoginWindow page. The Name is also very important (MainFrame). we’ll be referencing that in a minute.
Now, let’s add the navigation service. First, add an interface:
INavigationService base class is from MVVM Light.
Now add the class:
From the top:
_pagesByKey is Dictionary of page keys, and their uri address.
_historic is to keep the history
_currentPageKey is to keep the current loaded page.
NavigateTo function, gets a page key, and a parameter object. It then finds the frame we added to the
MainWindow, and sets the source to the uri that it gets from the dictionary.
GoBack, looks up the historic list, and calls
NavigateTo with what it finds. Configure functions is to populate the dictionary.
GetDescendantFromName is a helper function for finding the frame.
This code is taken form this repo
We then need to register the service into the locator.
Then call this in the constructor.
**Important: notice how we’re registering this service. If we instead register this the way we did IDataService, it would create a new instance every time and we had to call Configure in every view-model constructor. **
In the Login view-model, this is how we should change our login function:
And that’s it. now if you run the project, it should startup with the login page. then if you enter “admin” “admin”, it should navigate to the Main page.
Now, we’re going to do some messaging between view-models. For this, i’m going to add a side menu pane to the main page, and have the main page’s message, change as we click on each menu item. Just as simple as:
So default would be “Main Page” and we’ll simply change that with the menu item. the easiest thing ever. But first, let’s create the views. Change the MainPage.xaml as follows:
We’ve added another Grid element to be the father of all elements, and a DockPanel for the side panel. The dockpanel contains a ListBox of menu items. The ListboxItem template is defined a little higher in the same file. It’s a simple TextBlock element. Also we’ve added a SelectionChanged trigger to handle the clicks on menu items. It will call the command handler that’s defined in a view-model i’ll tell you about in a minute, and passes the ListBox’s SelectedItem property as CommandParameter.
We have a simple MenuItem class which is pretty straight forward. The rest is just as we already had. just simple Data binding. the new thing here, is the Messenger component to send the message. The message is just the name of the item. And it will be broadcasted to any class who has registered. Registering is also just as simple as this:
As you can see, we call “Register” function, and we pass in the current context, and a method to handle the message arrival. We simply append it to our message. And that’s it. If you run the program (and login), you can see how changing the items will change the message.
Don’t forget to register the view-model
In this article, we started by giving a small introduction on MVVM and the reason we use it. Then we wrote a small application using MVVM Light for visual studio 2019 on WPF. We discussed data bindings and commands. We added a login page which would compare input against a hard-coded credentials. Then we added navigation service to navigate to main page on login success.
I really hope i haven’t forgotten anything. But if in any case, you run into some problems, please take a look at the full code on