supported platforms examples serialization navigation viewmodel mvvmcross complextype

serialization - platforms - Pasar parámetros de navegación complejos con MvvmCross ShowViewModel



mvvmcross sqlite (2)

Mi tipo complejo no pasaría del método Show to Init incluso con el MvxJsonNavigationSerializer configurado como se especifica aquí Tipos personalizados en los parámetros de navegación en v3

public class A { public string String1 {get;set;} public string String2 {get;set;} public B ComplexObject1 {get;set;} } public class B { public double Double1 {get;set;} public double Double2 {get;set;} }

Cuando paso la instancia del objeto A al método ShowViewModel, recibo este objeto con String1 & String2 deserializado correctamente, pero CopmlexObject1 es nulo.

¿Cómo lidiar con la serialización de objetos complejos MvvmCross?


Creo que puede haber algunos gremlins en esa respuesta anterior: se registrará como un problema: /

Hay otras rutas posibles para lograr este tipo de navegación de objetos serializables complejos que aún usan Json y reemplazan partes del marco, pero en realidad creo que sería mejor usar su propio modelo de BaseView para hacer serialización y deserialización, por ejemplo, usar código de serialización como :

public class BaseViewModel : MvxViewModel { private const string ParameterName = "parameter"; protected void ShowViewModel<TViewModel>(object parameter) where TViewModel : IMvxViewModel { var text = Mvx.Resolve<IMvxJsonConverter>().SerializeObject(parameter); base.ShowViewModel<TViewModel>(new Dictionary<string, string>() { {ParameterName, text} }); } }

con deserialización como:

public abstract class BaseViewModel<TInit> : MvxViewModel { public void Init(string parameter) { var deserialized = Mvx.Resolve<IMvxJsonConverter>().DeserializeObject<TInit>(parameter); RealInit(deserialized); } protected abstract void RealInit(TInit parameter); }

luego un viewmodelo como este:

public class FirstViewModel : BaseViewModel { public IMvxCommand Go { get { return new MvxCommand(() => { var parameter = new A() { String1 = "Hello", String2 = "World", ComplexObject = new B() { Double1 = 42.0, Double2 = -1 } }; ShowViewModel<SecondViewModel>(parameter); }); } } }

puede navegar a algo como:

public class SecondViewModel : BaseViewModel<A> { public A A { get; set; } protected override void RealInit(A parameter) { A = parameter; } }


Una pequeña adición a la respuesta de Stuart para agregar seguridad tipo:

public class BaseViewModel: MvxViewModel { protected bool ShowViewModel<TViewModel, TInit>(TInit parameter) where TViewModel: BaseViewModel<TInit> { var text = Mvx.Resolve<IMvxJsonConverter>().SerializeObject(parameter); return base.ShowViewModel<TViewModel>(new Dictionary<string, string> { {"parameter", text} }); } } public abstract class BaseViewModel<TInit> : BaseViewModel { public void Init(string parameter) { var deserialized = Mvx.Resolve<IMvxJsonConverter>().DeserializeObject<TInit>(parameter); RealInit(deserialized); } protected abstract void RealInit(TInit parameter); }

ShowViewModel método ShowViewModel ahora toma el mismo tipo de parámetro que el método RealInit lugar de un tipo de object . Además, BaseViewModel<TInit> hereda de BaseViewModel para que sus instancias también puedan llamar al nuevo método ShowViewModel .

El único inconveniente es que debe especificar explícitamente el tipo de parámetro en la llamada como esta:

ShowViewModel<StoreInfoViewModel, Store>(store);