The default navigation mechanism in MvvmCross is deliberately lightweight.
It is really there to allow you to pass just one simple, serializable object - e.g.
public class DogNav
{
public int Id {get;set;}
public string Caption {get;set;}
}
// received in:
public class DogViewModel : MvxViewModel
{
public void Init(DogNav dogNav)
{
}
}
With this setup, if a navigation is triggered like:
// navigation
ShowViewModel<DogViewModel>(new DogNav() { Id=12, Caption="Good boy" });
then the underlying system will transport the values from that DogNav
object - possibly using Uri
s, Intents
or other serialization techniques - to the new DogViewModel
and will then ensure Init
is called with the correct values.
Because of the serialization, it's important:
- not to pass big objects (
Uri
s on WindowsPhone can break above a few hundred characters)
- not to expect the same object instance to arrive - i.e. if you are using database-backed or stateful objects, then it's best to pass some kind of lookup key rather than the objects themselves.
- not to expect that only one ViewModel will receive the message - on some operating systems, it may be that the user goes back and forth many, many times between apps causing many Views and ViewModels to be created.
- not to expect that a ViewModel that receives the message is in the same process and memory space as the ViewModel that sent the request - the same may actually be received days later after a tombstoning event.
If you do want to pass multiple objects via navigation, then I think you can do this using code like:
public class CatNav
{
public int CatId {get;set;}
public string CatCaption {get;set;}
}
public class DogNav
{
public int DogId {get;set;}
public string DogCaption {get;set;}
}
// received in:
public class CatAndDogViewModel : MvxViewModel
{
public void Init(DogNav dogNav)
{
}
public void Init(CatNav catNav)
{
}
}
In this case you could navigate using:
var catNav = new CatNav() { CatId =12, CatCaption="Meow" };
var dogNav = new DogNav() { DogId =12, DogCaption="Woof" };
var bundle = new MvxBundle();
bundle.Write(catNav);
bundle.Write(dogNav);
ShowViewModel<CatAndDogViewModel>(bundle);
I think this would work...
However... please be aware that the serialization is very simple - so if CatNav
and DogNav
were to share a property name, then this would lead to problems - you'd end up with some Cags and Dots
Because of the Cag and Dot problem I don't recommend this approach...
If you do need more complex transitions in your apps, then one route is to:
UPDATE - see Passing complex navigation parameters with MvvmCross ShowViewModel
1. Add the Json Plugin (or any Json serializer) and change your Setup.cs code to create a MvxJsonNavigationSerializer - overriding CreateNavigationSerializer
protected override IMvxNavigationSerializer CreateNavigationSerializer()
{
return new MvxJsonNavigationSerializer();
}
Use a composite object in navigation like:
public class DogAndCatNav
{
public DogNav DogNav {get;set;}
public CatNav CatNav {get;set;}
}
This would be received by:
public void Init(DogAndCatNav dogAndCatNav)
{
}
But note that this technique does need a more powerful serialization engine - such as Json.
Overall... even after writing all this... I'd recommend you pass as little data as possible in your navigations!