Modifying UWP navigation backstack with MvvmCross

While developing mobile apps, you may encounter the need to clear or pop the navigation stack to remove specific pages from appearing when the user navigates back. Because MvvmCross framework has a lot of abstractions above the target operating systems, it does not contain a built-in mechanism to manipulate the back stack. How can we use the framework capabilities to implement this requirement in a clean fashion?

Motivation

There are two very common scenarios where you may need to manipulate the back stack of your application.

If your app has a user area and login, you probably want your user to enter login view, enter his credentials and enter the user dashboard. After that navigating back to the login screen would make little sense as the user is already logged in. The solution is to pop the last entry in the navigation stack after navigating to the user area.

Login flow
Login flow

Second common scenario involving back stack is jumping to home view after the user navigates deep into your app. In this case we want to navigate home and clear the whole back stack afterwards.

Jumping home
Jumping home

UWP back stack 101

Universal Windows Platform uses the Frame  control to manage page navigation. The frame acts as a container which displays pages and maintains the navigation state. The most important property for us is the BackStack property, which is an IList  of PageStackEntry  objects.

Because the BackStack  is an IList , we can perform all the classic list operations on it. Hence, we can create two simple methods – one that pops the stack (removes the last entry) and one that clears it completely.

As you can see, we can use BackStackDepth  property to query the current depth of the back stack. Equivalently you can use BackStack.Count .

For those who are curious – in addition to the back stack, the Frame also maintains a forward stack, which means you could set up a navigation flow very similar to a classic internet browser with back and forward arrows just using the built-in frame control.

Integrating into MvvmCross

The logic for back stack manipulation is required in the ViewModel to be able to control when the specific steps of the stack should be removed. Unfortunately, because the specifics of the navigation are tied to the operating system, we cannot directly call our methods defined above from a portable class library.

Although we could build a service that does this for us, MvvmCross provides a cleaner solution in the form of presentation hints.

Presentation hints are classes that derive from MvxPresentationHint  and represent an intention to change the user interface presentation.

There is one built-in presentation hint in MvvmCross you have probably already met – the MvxClosePresentationHint . This hint is being created when you call the Close  method in your ViewModel and is handled by default by navigating back.

Creating Presentation Hints

The presentation hints should be defined in the Core PCL project and by convention stored in a PresentationHints folder/namespace.

Both our hints are just empty classes, because apart from the type of the hint we don’t need any additional info. Nothing stops you from building more complex hints with custom properties, however.

Changing presentation from ViewModel

MvxNavigatingObject class (which MvxViewModel  derives from) has a ChangePresentation  method which accepts one parameter of type MvxPresentationHint . The usage is very simple:

Handling the presentation change request

The presentation hint is raised in the PCL but has to be handled in a platform specific manner inside the app project itself.

MvvmCross implements a concept of view presenters. These implement the IMvxViewPresenter  interface which has the following signature:

As you can see, the view presenters already have a built-in support for presentation hints. Each platform implements a default view presenter, for Windows we have the MvxWindowsViewPresenter , which has the default behavior of Frame navigation implemented. You may implement more complex view presenters if your app requires such. The default is sufficient for us, because we will just use the AddPresentationHintHandler  method to register handlers for our presentation hints.

First we create a class that takes a IMvxWindowsFrame  (which is a wrapper around the Frame  control) and contains handlers for our hints:

In addition to manipulating the back stack we are returning true or false if the hint was handled or was not, respectively. This is useful if we want to have multiple different handers for a single presentation hint.

Now the last thing left to do is to register our handlers. We can do this by overriding the CreateViewPresenter  method in Setup class of the UWP project.

We let the framework create the default view presenter and then add our two presentation hint handlers. This way they are registered and will be invoked when presentation change is hinted.

Source code

Sample source code for this post is available on my GitHub. This includes a working example app.

Summary

We have shown how we can manipulate the back stack in MvvmCross-based app in a clean manner. To accomplish this we took advantage of framework’s presentation hints which are then handled in the app’s view presenter.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

*