2013-09-27 15 views
15

mio tipo complesso non passerebbe da Show al metodo Init anche con configurato MvxJsonNavigationSerializer come specificato qui Custom types in Navigation parameters in v3Passaggio di parametri di navigazione complessi con 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;} 
} 

Quando passo istanza di oggetto AL metodo ShowViewModel ricevo questo oggetto con String1 & String2 deserialized correttamente ma CopmlexObject1 è null.

Come gestire la serializzazione MvvmCross dell'oggetto complesso?

+0

ero in grado di risolvere questo problema con l'aggiunta di plugin di JSON mvvmcross nel mio progetto UIView. –

risposta

25

Credo che ci possono essere alcuni Gremlin che risposta precedente - sarà il login come un problema:/


Non ci sono altre vie possibili per raggiungere questo tipo di complesso di navigazione oggetto serializzabile che ancora utilizzano JSON e parti imperative del framework, ma in realtà penso che potrebbe essere meglio usare semplicemente il proprio BaseViewModel per effettuare serializzazione e deserializzazione - ad es. utilizzare codice di serializzazione come:

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 deserializzazione come:

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

poi un ViewModel come questo:

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

può passare a qualcosa di simile:

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

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

registrati come https://github.com/slodge/MvvmCross/issues/450 – Stuart

+0

Grazie! Un approccio interessante e che funzionerà sicuramente perché controllo completamente il processo di serializzazione/deserializzazione da solo. –

8

A piccola aggiunta a Stua La risposta di rt per aggiungere sicurezza tipo:

metodo
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 prende ora lo stesso tipo di parametro che il metodo RealInit invece di un tipo object. Inoltre, BaseViewModel<TInit> eredita da BaseViewModel in modo che le relative istanze possano chiamare anche il nuovo metodo ShowViewModel.

L'unico inconveniente è che si deve specificare esplicitamente il tipo di parametro nella chiamata in questo modo:

ShowViewModel<StoreInfoViewModel, Store>(store);