This series of articles documents how to use the MVVM Light NavigationService on all supported platforms.
Why use the INavigationService interface?
Navigation works very differently depending which platform the application runs on. There are different scenarios:
Some frameworks have a navigation concept with a built-in navigation journal. There is a concept of Forward and Back navigation which is supported by the built-in navigation service. For instance, Windows Phone has a built-in navigation service (the Frame) and a back button on the phone. iOS has a navigation service as well (the NavigationController), and a Back button in a navigation bar that can be placed on every page.
On Android, there is a concept of Forward and Back navigation, with a back button on the phone, but there is no built-in navigation service. A “forward navigation” consists of starting a new Activity. A “back navigation” consists of ending the current Activity and restarting the previous one.
Sometimes there isn’t really a built-in forward and back navigation. For example in WPF, we mostly work with windows. The navigation may consist in showing a user control in an area of the main window, or in opening a secondary window, etc. There isn’t really a standard way to navigate there. Note: You can also implement page based navigation in WPF but this scenario is quite rare and I won’t even go into that in this series.
In some cases, it can be interesting to trigger the navigation from the ViewModel layer. But since this layer is shared between multiple frameworks (for example Android, iOS, Windows Phone, Windows Store etc), we need to abstract the way that the navigation works. This is the role of the INavigationService interface. The MVVM Light’s INavigationService is quite simple, and should be sufficient for many navigation scenarios. It can also be extended or replaced easily by more complex implementations if needed.
Important: Note that the INavigationService implementation should be complementary to the built-in navigation of the framework (if there is one). In other words, when a built-in navigation service and navigation journal exist, these should be used. For the application, it shouldn’t make any difference if the navigation is triggered from the page itself or from a shared viewmodel.
In MVVM Light, the INavigationService is available in the GalaSoft.MvvmLight DLL, within the GalaSoft.MvvmLight.Views namespace. It is typically used in conjunction with an IOC container, such as MVVM Light’s SimpleIoc and injected into the shared code, such as viewmodels. The following paragraphs will describe the members of the INavigationService interface.
The NavigateTo method
The NavigateTo method navigates to a different page (where supported) or shows a different portion of the UI (such as a UserControl or a Window) depending on a key. In order to abstract the differences between all the supported frameworks, the key is a simple string. In response, the implementation must show the page that corresponds to this key.
There are two overloads of the NavigateTo method:
This is a simple navigation to a page, defined by the pageKey parameter. The pageKey is typically a constant in the application.
Most frameworks support multiple navigation to the same page (for example Page1 –> Page2 –> Page2 –> Page3). The only exception so far is Windows Phone Silverlight applications. For more details, consult the specific article dedicated to this framework.
NavigateTo(string pageKey, object parameter)
This navigation includes a parameter which will be passed to the target page. Depending on the framework, there are different ways to retrieve the passed parameter (see the next articles in the series for an explanation for each framework).
You can navigate multiple times to the same page with a different parameter (for example Page1 –> Page2+param1 –> Page2+param2 –> Page3).
The GoBack() method
This method is quite simple: It will go back one step in the navigation journal. For example, if you navigated Page1 –> Page2 –> Page3, calling GoBack will go to Page2 first, then Page1.
The implementation of GoBack should be complementary to the back button usage (either built into the device, or placed on the UI). In other words, there should be no differences in the behavior of the application if the back navigation is triggered from a button on the page, or from the device’s built-in back button (if there is one).
The CurrentKey property
This property returns the key corresponding to the current page. The key returned is the one passed to the NavigateTo method. In order for this property to work, the NavigationService implementation needs to be informed of all the existing navigation keys and the corresponding pages. Each supported framework works a little differently in that regard, typically by using a method called Configure. For more details, check the following articles in this series.
An abstracted navigation method is crucial when you want to share code between the platforms. Because each platform supports navigation in a different manner (if it supports it at all), it is important to abstract these differences so that the underlying shared code is not impacted by these changes. The INavigationService interface (in conjunction with an IOC container such as the MVVM Light’s SimpleIoc) allows this level of abstraction quite easily and in an elegant manner.