2013-09-27 16 views
15

Mein komplexen Typ nicht von Show zu Init-Methode auch mit konfiguriert MvxJsonNavigationSerializer passieren würde, wie hier angegeben Custom types in Navigation parameters in v3Passing komplexe Navigationsparameter mit MvvmCross ShowViewModel

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;} 
} 

Wenn ich Instanz des Objekts A zu ShowViewModel Methode übergeben ich diese erhalten Objekt mit String1 & String2 korrekt deserialisiert, aber CopmlexObject1 ist null.

Wie mit komplexen Objekt MvvmCross Serialisierung umzugehen?

+0

konnte ich dieses Problem beheben mvvmcross json-Plugin in meinem uiview Projekt hinzufügen. –

Antwort

25

Ich glaube, es in dieser vorherigen Antwort einige Gremlins sein kann - wird als ein Problem log:/


Es gibt andere mögliche Routen dieser Art von komplexen serializable Objektnavigation noch mit Json und übergeordnete Teile zu erreichen des Frameworks, aber eigentlich denke ich, dass es besser sein könnte, einfach mit eigenen BaseViewModels Serialisierung und Deserialisierung durchzuführen - z verwenden Serialisierungscode wie:

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} 
      }); 
    } 
} 

mit Deserialisierung wie:

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); 
} 

dann ein Ansichtsmodell wie folgt aus:

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); 
       }); 
     } 
    } 
} 

zu so etwas wie navigieren können:

public class SecondViewModel 
    : BaseViewModel<A> 
{ 
    public A A { get; set; } 

    protected override void RealInit(A parameter) 
    { 
     A = parameter; 
    } 
} 
+0

angemeldet als https://github.com/slodge/MvvmCross/issues/450 – Stuart

+0

Vielen Dank! Interessanter Ansatz und das wird definitiv funktionieren, da ich den Serialisierungs-/Deserialisierungsprozess vollständig selbst kontrolliere. –

8

A kleiner Zusatz zu Stua rt Antwort Typ Sicherheit hinzuzufügen:

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 Methode nimmt nun den gleichen Parameter-Typ, die das RealInit Verfahren anstelle eines object Typ. Außerdem erbt BaseViewModel<TInit> von BaseViewModel, so dass ihre Instanzen auch die neue Methode ShowViewModel aufrufen können.

Der einzige Nachteil ist, dass Sie explizit den Parametertyp in dem Aufruf wie folgt angeben:

ShowViewModel<StoreInfoViewModel, Store>(store);