Codon is a zero-dependency cross-platform MVVM framework for creating UWP, WPF, and Xamarin based applications. It provides much of what you need to rapidly create sophisticated yet maintainable applications.
In the previous article you looked at enabling communication between components in your app using the
Messenger class. In this article, you look at enabling page navigation using the routing service in conjunction with the navigation service.
The code presented herein is located in Sample001 in the Samples repository
The page navigation APIs differ significantly across platforms. Some platforms, like the UWP, allow you to navigate to a page using its
Type. In WPF, you navigate to a Page instance. While others use a completely different scheme, such as Android and its use of
To ease these differences, Codon employs a routing system, that allows you to register a string URL with an associated
Action. When the navigation service receives a request to navigate to a particular URL, the action associated with that URL is invoked.
NOTE: The URL can, in fact, be any string, and serves merely as a key to look up the associated Action.
Understanding the Routing Service
Codon does not require bootstrapping. Various default IoC container registrations are performed automatically. However, if you intend to use Codon’s navigation service for anything besides back navigation, you need to configure its routes.
In the sample, you can find a class named
Bootstrapper in each platform project. Its sole purpose is to configure the routing service.
Each of the
Bootstrapper classes contain a
Run method, which is called when the application launches. The
Bootstrapper in the UWP sample project, retrieves the
IRoutingService from the IoC container and registers the URL “/Page2” (contained within the Routes class) with an
Action to call the
Navigate method. See Listing 1.
Listing 1. UWP Sample Bootstrapper class.
public void Run()
var routingService = Dependency.Resolve<iroutingservice>();
Navigate method calls the non-generic navigate method, which then retrieves the
Frame object from the
Window, and calls its
Navigate method with the page
Type as a parameter. See Listing 2.
NOTE: You don’t have set up the
Bootstrapper like this. It’s merely a guide. Remember, the routing service accepts an
Action, so the flexibility is there to do whatever you like.
Listing 2. UWP Bootstrapper Navigate methods
void Navigate(Type pageType)
var frame = (Frame)Window.Current.Content;
Bootstrapper for WPF looks much the same as the UWP
Bootstrapper, apart from its
Navigate method. See Listing 3.
INavigationService implementation for WPF contains a convenient helper method, which locates the built-in
System.Navigation.NavigationService from current
Window. Since we know the
Bootstrapper is running on WPF we can safely cast the
INavigationService to its concrete implementation
Bootstrapper uses the
Dependency class to build-up the new page, which is then passed to the built-in
Listing 3. WPF Sample Bootstrapper Navigate method
void Navigate(Type pageType)
var navigationService = (NavigationService)Dependency.Resolve<inavigationservice>();
var page = Dependency.ResolveWithType(pageType);
Bootstrapper class in the Sample Android app, works much the same as the other platforms. The main difference, however, is that it makes use of Android
Run method retrieves the
IRoutingService instance and registers a Page 2 route with an associated call to the
LaunchActivity method, as shown:
routingService.RegisterPath(Routes.Page2, () => LaunchActivity<page2activity>(1));
Navigating in Xamarin Android requires an
Context object. Because there isn’t a global handle to the current
Activity, Codon requires that when an
Activity becomes active, it is registered with the IoC container.
LaunchActivity method of the Android Sample
Bootstrapper retrieves the current
Activity from the IoC container. See Listing 4. It then creates an
Intent for the new activity. The new activity is started using the
Intent object and a request code. There will be more on request codes in a later article.
Listing 4. Android Sample Bootstrapper LaunchActivity methods
void LaunchActivity<tactivity>(int requestCode)
void LaunchActivity(Type activityType, int requestCode)
var activity = Dependency.Resolve<activity>();
Intent intent = new Intent(activity, activityType);
Navigation via a View-Model Command
Returning to the
Page1ViewModel, you see that the
NavigateToPage2Command calls the view-models
NavigateToPage2 method, as shown:
public ICommand NavigateToPage2Command => navigateToPage2Command
?? (navigateToPage2Command = new ActionCommand(NavigateToPage2));
NavigateToPage2 method uses the navigation service to navigate to the URL defined in Routes.Page2 (“/Page2”). See Listing 5. The navigation service then asks the routing service if there is a route registered with the URL “/Page2”, and as there is, invokes the
Action associated with the URL; navigating to the second page.
Listing 5. Page1ViewModel NavigateToPage2 method
void NavigateToPage2(object arg)
So, to recap: Use the
IRoutingService to associate URLs with
Actions that perform the actual navigation. Use the
INavigationService to navigate to the URLs.
Back Navigation via a View-Model Command
There is a button on each of the platform Page1 views that is bound to the
NavigateToPage2Command. When activating the button, the UWP/WPF/Android apps navigate to Page 2. On Page 2 there is a button that is bound to the
NavigateBackCommand. When the command executes, the
INavigationService is called upon to perform a back navigation, like so:
void NavigateBack(object arg)
Each platform specific implementation of
INavigationService knows how to perform a back navigation for its particular platform.
In this article, you look at enabling page navigation using the routing service in conjunction with the navigation service.
I hope you find this project useful. If so, then please rate it and/or leave feedback below.
April 2 2017