Having covered basic navigation, I found that I needed to pass my game state from view-model to view-model. I initially thought that I could simply do this as follows:
private void CallVM2()
{
MyObj newObj = new MyObj();
IMyService myService = new MyService();
Dictionary p = new Dictionary()
{
{"MyObj", newObj},
{"MyService", myService}
};
ShowViewModel(p);
}
The code for ViewModel2:
public void Init(Dictionary p)
{
}
Anyway, it turns out you can’t. Init does get fired, but if you pass anything more complex than a string, it just bins the parameter.
The answer appears to be to create a class and to serialise it using JSON.NET:
After implementing this suggestion, I ended up with something like this:
public abstract class BaseViewModel : MvxViewModel
{
private const string ParameterName = "parameter";
public BaseViewModel()
{
}
protected void ShowViewModel(object parameter) where TViewModel : IMvxViewModel
{
var text = Mvx.Resolve().SerializeObject(parameter);
base.ShowViewModel(text);
}
public void Init(string parameter)
{
if (parameter == null || parameter.Length == 0) return;
IMvxJsonConverter converter = Mvx.Resolve();
NavigationParameter deserialized = converter.DeserializeObject(parameter);
RealInit(deserialized);
}
}
If you don’t register the converter in the IoC container (as I initially didn’t), then you’ll get this error:
A first chance exception of type ‘Cirrious.CrossCore.Exceptions.MvxIoCResolveException’ occurred in Cirrious.CrossCore.DLL
Additional information: Failed to resolve type Cirrious.CrossCore.Platform.IMvxJsonConverter
The fix:
public abstract class BaseViewModel : MvxViewModel
{
private const string ParameterName = "parameter";
public BaseViewModel()
{
Mvx.RegisterType();
}
Now, if you override the `RealInit` method, you’ll see that the parameters are, indeed, available. However, I had a further problem; this time being with JSON.NET. As you can see from the above structure, it’s a dictionary of objects. So, when running this, it will certainly pass through the object, but it’ll just be the serialised string.
And…?
I’m pretty sure that I could get around this using a combination of generics and a custom Javascript serialisation library, but I’ve got a game to write, so I’m going to stick with declaring the Navigation parameter as follows:
public class NavigationParameter
{
public MyObject ObjectParameter { get; set; }
public MyService ServiceParameter { get; set; }
}
It’s worth bearing in mind that you can’t use interfaces either in the parameters; JSON.NET needs a concrete class.