Skip to content

Wolf Programmer Posts

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.

Custom App Header in Forms

iOS Navigation Bar NestedIt is safe to assume that any business with a customer facing application will want to brand their application with at least their logo. From the very onset of using Xamarin.Forms, I found myself annoyed with the lack of customizability of the navigation bar for iOS. To be fair, it is a pain to customize on the native side; however, the Forms’ abstraction removes most of your options.

NOTE: the navigation bar shows up when a Page is nested within a NavigationPage; this creates a navigation stack.

The equivalent implementation for Android is a toolbar or action bar. Within the Android project, you can customize the toolbar using the native Toolbar.axml layout file. Unfortunately, in order to customize the iOS navigation bar to the same extent as Android requires a custom renderer and a fair amount of hacking. Even with the ability to manipulate the look of the iOS navigation bar using a custom renderer, both platforms are now diverging from each other (not to mention if you support Windows). This messy solution wasn’t going to work for me. Two simple features resolved this dilemma.

I came to the realization that I could not use the navigation bar (iOS) or toolbar (Android) and maintain a unified solution between platforms. Simply put, I wanted the platform specific bars to disappear. Thankfully, Xamarin provides a simple way to turn them off. Using the static reference to NavigationPage provides the method SetHasNavigationBar. This method takes two parameters, the page the setting applies to and the boolean value.

At this point my navigation stack no longer has a header. This allows me to add a completely custom implementation that will work for all platforms. An easy way to create such a header is with the combination of a boxview, a back button, and a logo. The specifics are not important because it will vary greatly between applications. An example could look like the following:

But how do I apply this XAML to each of my pages?! This can be accomplished with a ControlTemplate. A ControlTemplate is a UI template that can be applied to any XAML page. You’ll define the template in the ResourceDictionary located in the App.xaml file. You will also include a ContentPresenter within the template. A ContentPresenter is the content area or body of the pages the template is being applied to. The ControlTemplate Key will be used to reference the template in your pages.

Once the ControlTemplate is created, we need to apply it to our Pages. This is accomplished by adding a StaticResource reference of the template Key inside our pages’ ControlTemplate property in the XAML.

iOS Custom App HeaderYou now have a fully customizable header for your application. You can add EventHandlers, Commands, or GestureRecognizers to interact with your header as needed. You will have to implement the back button logic as well.

Why should software developers have a blog?

Of the many conference sessions I attended at Xamarin Evolve16 this year, there was one that was radically different than the others. When you go to a developer conference, you assume that all the sessions are focused entirely around the latest technology trends and improving your development skills. What I did not expect was a session on skills to improve the quality of life and long term success as a software developer. As software developers, we have very analytical minds, and thus we only focus on our quantitative technical skills and ignore the qualitative. In the session, 5 Soft Skills Every Software Developer Should Know, I was introduced to John Sonmez, and his mission is to change that.

John Sonmez is a software developer who was so successful in his day job, he was able to retire at the age of 33. Since then, he has become a software developer coach who has made it his life’s mission to helping developers succeed in their careers and surpass mediocre lives. John has built a unique business revolving around this core mission, called Simple Programmer.

Simple Programmer provides a multitude of services for software developers including blog posts, podcasts, YouTube videos, published books, and training courses. A large majority of this content is completely free and worth exploring.

One course in particular that is worth investigating is his free email course on building a blog. In this course, John sends you weekly emails explaining the simple process of how to build a blog correctly and the reasons for it.  While the content of his emails might first appear to be common sense, if they were so common, why do some many developers do it incorrectly, or not at all?

That’s nice, but why should I even care about blogging? The premise behind developers maintaining a blog is that it acts as a conduit to creating a brand for yourself.  Developers without a brand (or name for themselves) are simply code monkeys that can be easily replaced with another developer. Adversely, developers that have both the technical skills and name recognition within an industry are sought out by employers. In essence, you want to be name not a number in a stack of resumes.

Beyond simply name recognition within an industry, blogging provides a channel of communication between other developers. While Stack Overflow is the usual go to for quick technical issues, blogs are the second resource type that ALL developers depend on. Not only are they another tool in our tool-belt, they are also better mediums for more in depth topics; the format is more conducive for tutorials and longer articles than Stack Overflow.

Most developers usually have a healthy level of skepticism. Why should we trust this John guy whom you might not have ever heard of before? Don’t just listen to him, listen to the advice of other major names in the industry like Scott Hanselman. While John’s advice isn’t some magic get rich quick pill, his advice is a compilation of life skills for developers that, with hard work, could completely change the course of your career.

Xamarin.Forms Structure

In the previous blog post, we created a Xamarin.Forms Portable Class Library (PCL) solution. In this blog post, we will discuss the actual file structure of that same solution and deploy it to an actual simulator.

Hello Forms Root Solution StructureAfter creating the solution, you will notice three separate projects (i.e. HelloForms, HelloForms.Droid, and HelloForms.iOS). If you are at all familiar with Xamarin native projects, the structure of the Android and iOS Forms projects are virtually identical to the native. Adversely, you will notice an additional project named HelloForms; this is the PCL.

HelloForms iOS ProjectThe PCL acts as the core of your application and will contain a majority of your code (if this is not the case, you should probably stick with Xamarin native).

Contained within the iOS project, is a file named Main.cs. This file acts as the main entry into your iOS application. Main.cs will simply instantiate our AppDelegate.cs file.

Inside our AppDelegate.cs file is where the Forms magic begins. Forms is first initialized and a new instance of the PCL’s App.cs class is loaded.

HelloForms Android ProjectBefore we discuss the PCL App.cs class, let’s switch over to see how Android launches. Inside the Android project, you will find the MainActivity.cs file. Android simplifies the process by combining the entire launch process into this one file. The MainActivity.cs file both acts as the main entry into the application and also initializes Forms and instantiates the PCL’s App.cs class. Android does not use the MainActivity.cs file as the entry point due to the name, it is used because it contains the “MainLauncher = true” attribute.

HelloForms PCL ProjectBoth platforms have now entered PCL land. If we open the PCL project, we can now look inside the App.cs file… However, an App.cs class does not seem to exist. If you recall from the last blog post, we opted to use XAML to build our UI. Therefore, App.cs is actually called, App.xaml. You will notice that there is an expandable indicator next to the App.xaml file. Once you expand the file, you will see an App.xaml.cs file nested below the App.xaml file. App.xaml.cs is the C# code behind our XAML file. Inside our code behind file, we have a constructor which sets the first page for our application, and the self explanatory OnStart(), OnSleep(), and OnResume() methods. We will use the App.xaml.cs class in later blog posts to accomplish more advanced functionality.

From the App.xaml.cs code behind, we discover that HelloFormsPage() is set as our MainPage. This is simply a template page that was created when we created the solution. We can change this later; however, let’s use it for this example. In Xamarin.Forms, pages are views that occupy the entire screen. This page is essentially the equivalent to a UIViewController’s UIView in iOS or an Activity’s View in Android. Similar to the App.cs file, the HelloFormsPage is made up of both a XAML file and a C# code behind file.

We will go much deeper into XAML in later blog posts; however, just so you can get a taste for it, open the HelloFormsPage.xaml file. You will notice on line 3 that there is a Label. Update the text from “Welcome to Xamarin Forms!” to “Hello Xamarin.Forms” (be careful, the text for this label must be encapsulated in double quotes). Save your changes.

Xamarin Studio Set As Startup ProjectWe are now ready to build and launch our application. Right click on the iOS project, and select “Set As Startup Project”. Xamarin Studio Start Debugging IconYou can now select the build and deploy icon (looks like the play icon you would find on a tv remote).  This will build the application and deploy it to an iOS simulator on your Mac. To stop the application, you can hit the stop icon in Xamarin Studio (same button location as the play icon).

To launch the Android application, right click on the Android project, and select “Set As Startup Project”. Click the play icon (aka Build and Deploy). A default Android emulator should launch.

Android HelloForms App iOS HelloForms App

Congrats on building your first Xamarin.Forms app!