Skip to content

Tag: MVVM

Navigation using MVVM Light

MVVM Light is one of many free MVVM frameworks available today. As the name implies, MVVM Light is a lightweight framework that allows the developer to utilize as much or as little of the framework as is needed.

Conversely, other MVVM frameworks are more of an “all or nothing” design. The problem with the “all or nothing” design is that they essentially replace the base system that you are developing on. For instance, if you are developing with Xamarn.Forms, and you adopt one of beefier MVVM frameworks, the framework will completely override a large percentage of how Forms was intended to operate. This can cause major frustration when reading blogs, tutorials, and other coding examples.

As we discussed in the previous post, Forms utilizes XAML for UI implementations and thus is intended to follow the MVVM design pattern. That being said, a large percentage of Xamarin developers (including myself) agree that Forms does not by default correctly handle navigation using the MVVM pattern because the Views dictate the navigation logic not the ViewModels.

For anyone that is just starting out with Forms, navigation can be very frustrating. Fortunately, there is an easy solution to move navigation logic from the Views to the ViewModels using MVVM Light.

We first need to add the MVVM Light package to each project in our solution (PCL, Android, iOS, and any flavor of Windows that you are supporting).

  1. Right click Packages in the solution explorer
  2. Click Add Packages
  3. Use NuGet’s search function to find MVVM Light libraries only package (Id: MvvmLightLibs, Author: Laurent Bugnion (GalaSoft))
  4. Add Package (to each project)

MVVM Light will add the dependency CommonServiceLocator package by Microsoft. Before we implement our navigation service, we need a way to globally access this service so that all ViewModels have access. This is where the Locator comes into play.

In the PCL project, create a folder called Services. Within the Services folder create a class called Locator. We only want one Locator for the entire application, so we will follow the singleton pattern and make the Locator constructor static.

There are three main components to this class, the string constants at the top, the constructor, and various properties with getters. The constants act as keys for each page registered for the navigation service. The constructor handles all the registration of services and ViewModels; ViewModels do not have to be created within the locator, they can be instantiated by the view. Finally we expose the Navigation Service and ViewModel instances with property getters.

Next, let’s implement the NavigationService. In the same folder as the Locator, create a class called NavigationService. This class will implement the MVVM Light (GalaSoft) INavigationService interface. Add the following methods and properties:

At this point, we still do not have a globally accessible NavigationService. Open the class code-behind that implements Application; this is usually called App.xaml.cs. Add the following locator property:

Our ViewModels are now able to completely handle our navigation logic using App.Locator.NavigationService.NavigateTo(PAGE KEY).

Example:  App.Locator.NavigationService.NavigateTo(Locator.SecondPage);

This tutorial is based off of Mark’s Blog.

Xamarin.Forms, MVVM, and Navigation

Coming from a Xamarin native background, I was not entirely familiar with the MVVM pattern prior to switching to Xamarin.Forms. The native designs for iOS and Android typically follow the MVC pattern. MVVM was designed by Microsoft specifically for applications that utilize XAML to design their UIs. If you are familiar with MVC, MVVM is not wildly different. MVVM stands for Model-View-ViewModel.

MVVM Pattern
Source: Microsoft.com

A very rudimentary way to describe MVVM is that you have your typical data models which make up the Model part of the acronym. These data models represent the objects and business logic within your application. Next, we have the View; this is exactly what it sounds like, essentially everything that is rendered on the screen is part of the View.  The ViewModel is the unique (or not so unique) aspect of the pattern. This is where all of your view logic and states are handled. Additionally, the ViewModels act as the middleman between the Views and the Models.

The main objective to using the MVVM pattern is to create loosely coupled code between the Views and the ViewModels. In other words, the Views know about the ViewModels; however, the ViewModels should not know about the Views. Additionally, the Views should not know about the (data) Models and the Models should not know about the Views, or the ViewModels. The purpose behind such a design allows developers to quickly and easily swap out Views with other Views without having to change the business and application logical. Furthermore, this design allows separate teams to work on different components of the project. For example, on a large team, designers could work on the Views of the application (in XAML without any other programming knowledge), while developers could handle the ViewModels, and Models.

Xamarin.Forms was designed with MVVM in mind due to the adoption of XAML. Most of the framework has implemented the tools necessary to utilize the MVVM pattern. However, in my opinion (and the opinion of others) one aspect of the framework design completely breaks the MVVM pattern, and that is navigation.

Xamarin.Forms handles navigation using the INavigation interface available on any Page type (aka the Views). INavigation acts as a globally available navigation stack for your entire application. You might be thinking, that’s great, what’s the problem? The main problem, is that the Views are in charge of handling navigation, not the ViewModels. This technically breaks the MVVM pattern because the Views are dictating how your application operates, not the ViewModels. Under this design, it becomes very difficult to replace a particular View without fixing the logical structure of your application.

So what’s the solution? The solution is to move all of your navigation logic into your ViewModels. In my next post, I will go into detail of how to do this using a framework called MVVM Light.