Wednesday, January 02, 2013

Navigating between ViewModels by more than just strings...

One of the questions that has come up a few times on StackOverflow is about why MvvmCross insists on using Strings for ViewModel navigation parameters.

The answer to this has always been that these are used in order to ensure that the navigation can be serialised down into a Xaml Uri or into an Android Intent. e.g. see the question and answer in

The good news is that from a checkin on New Year's Eve, strings are now not the only option - you can now use:
  • string
  • long
  • int
  • double
  • your own custom enums

To see the changes that enabled this, see the commit at:

For an example of integer use, see the way I modified the Conference sample:


These changes, however, still ask the user to use lists of parameters.... and these parameters lists can get quite long...

One request on Jabbr was:

  • gshackles:

    one of the things I don't like is that i'm just passing these anonymous objects around with magic properties

    would prefer to have a class for the parameters to a view model and just pass that in

    would also make it much more resistant to refactoring too

This seemed like a very reasonable request.... and the good news is that you can add this yourselves by:
  • overriding the way navigations are requested 
  • and overriding the way ViewModels are located.

Here's one way to achieve this:

First, create the base type for all your navigation parameter objects

Then modify your BaseViewModel (or ViewModelBase) in order to allow it to support this parameter object navigation

Now modify each of your view models so that they have a new NavigateTo method - which either take no argument or which take a class derived from NavigationParametersBase:

Now, create a default ViewModelLocator which can deserialise the incoming NavigationParameters and can initialise the ViewModel:

Note that this method uses a new deserialise method - only just added:

Finally, to make sure that the locator is used, override CreateDefaultViewModelLocator in your MvxApplication:

That's it.

Obviously, there's more that could be done - and different ways in which the ViewModel could be initialised - but this is a basic start which others can build on if they want to.

No comments:

Post a Comment