2013-09-27 23 views
15

Mojego typu złożonego nie przechodzą z Pokazują metodą Init nawet ze skonfigurowanym MvxJsonNavigationSerializer jak określono tutaj Custom types in Navigation parameters in v3Przekazywanie złożonych parametrów nawigacyjnych z 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;} 
} 

Kiedy mijam wystąpienie obiektu A do sposobu ShowViewModel otrzymam ten obiekt z String1 & String2 deserialized poprawnie, ale CopmlexObject1 ma wartość null.

Jak radzić sobie z serializacją obiektów złożonych MvvmCross?

+0

udało mi się rozwiązać ten problem poprzez dodanie mvvmcross wtyczki json w moim projekcie UIView. –

Odpowiedz

25

wierzę, mogą istnieć pewne gremlins w tej poprzedniej odpowiedzi - będzie rejestrować jako problem:/


istnieją inne możliwe drogi do osiągnięcia tego rodzaju złożonego serializable obiektu nawigacji nadal używając JSON oraz części nadrzędne ramy, ale tak naprawdę myślę, że lepiej byłoby po prostu użyć własnego BaseViewModel do serializacji i deserializacji - np. użyć kodu serializacji jak:

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

z deserializacji jak:

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

następnie ViewModel tak:

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

może przejść do czegoś takiego:

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

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

zalogowany jako https://github.com/slodge/MvvmCross/issues/450 – Stuart

+0

Dziękujemy! Interesujące podejście i to z pewnością zadziała, ponieważ sam w pełni kontroluję proces serializacji/deserializacji. –

8

A mały dodatek do Stua Odpowiedź RT, aby dodać bezpieczeństwa typu:

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 metoda obecnie zajmuje ten sam typ parametru, że metoda RealInit zamiast typ object. Ponadto, BaseViewModel<TInit> dziedziczy po BaseViewModel, więc ich wystąpienia mogą również wywoływać nową metodę ShowViewModel.

Jedyną wadą jest to, że trzeba wyraźnie określić typ parametru w wywołaniu tak:

ShowViewModel<StoreInfoViewModel, Store>(store); 
Powiązane problemy