2012-04-24 4 views
7

Utilizzo di MvvmCross su un progetto mobile multipiattaforma e ho 2 visualizzazioni diverse in un progetto MonoTouch che utilizzano lo stesso modello di visualizzazione condiviso e non sono sicuro di come strutturare il mio codice per navigare viste differenti usando lo stesso viewmodel in MvvmCross.MvvmCross - Condivisione di modelli di visualizzazione per più viste

risposta

11

La convenzione di default utilizzata dalla piattaforma MvvmCross consiste nel registrare automaticamente tutte le viste mediante la riflessione.

Questo viene fatto in classe di installazione di base - in https://github.com/slodge/MvvmCross/blob/master/Cirrious/Cirrious.MvvmCross/Platform/MvxBaseSetup.cs:

protected virtual void InitializeViews() 
    { 
     var container = this.GetService<IMvxViewsContainer>(); 

     foreach (var pair in GetViewModelViewLookup()) 
     { 
      Add(container, pair.Key, pair.Value); 
     } 
    } 

dove GetViewModelViewLookup restituisce un dizionario di tipo ViewModel al tipo di vista:

protected virtual IDictionary<Type, Type> GetViewModelViewLookup(Assembly assembly, Type expectedInterfaceType) 
    { 
     var views = from type in assembly.GetTypes() 
        let viewModelType = GetViewModelTypeMappingIfPresent(type, expectedInterfaceType) 
        where viewModelType != null 
        select new { type, viewModelType }; 

     return views.ToDictionary(x => x.viewModelType, x => x.type); 
    } 

In universale iPad/iPhone apps che fai ogni tanto vuoi includere più viste per ciascun modello di vista - utilizzando una vista nell'iPad e una vista nell'iPhone.

Per fare questo, ci sono ora (letteralmente solo ora!) Alcuni attributi disponibili per contrassegnare le vostre opinioni come "non convenzionale" - questi sono:

L'ultimo di questi è probabilmente quello che volete in questo caso - si potrebbe implementare semplice commutazione iPhone/iPad per una MainViewModel utilizzando due viste dichiarato come:

[MvxFormFactorSpecificView(MvxTouchFormFactor.Phone)] 
public class MyIPhoneView : BaseView<MainViewModel> 
{ 
    // iphone specific view ... 
} 

[MvxFormFactorSpecificView(MvxTouchFormFactor.Pad)] 
public class MyIPadView : BaseView<MainViewModel> 
{ 
    // ipad specific view ... 
} 

In alternativa, se si desidera una configurazione molto personalizzata, è possibile ignorare tutti i comportamenti basati sulle convenzioni - è possibile implementare il proprio override di GetViewModelViewLookup - ad es.:

protected override IDictionary<Type, Type> GetViewModelViewLookup(Assembly assembly, Type expectedInterfaceType) 
{ 
    if (IsIPad) 
    { 
     return new Dictionary<Type, Type>() 
     { 
      { typeof(HomeViewModel), typeof(IPadHomeView) }, 
      { typeof(DetailViewModel), typeof(IPadDetailView) }, 
      { typeof(AboutViewModel), typeof(SharedAboutView) }, 
     }; 
    } 
    else 
    { 
     return new Dictionary<Type, Type>() 
     { 
      { typeof(HomeViewModel), typeof(IPhoneHomeView) }, 
      { typeof(DetailViewModel), typeof(IPhoneDetailView) }, 
      { typeof(AboutViewModel), typeof(SharedAboutView) }, 
     }; 
    } 
} 

Nota che alla fine si può decidere che è necessario ViewModels aggiuntivi e vista per l'applicazione iPad - iPad ha, dopo tutto, uno schermo molto più grande - in questo caso si può aggiungili manualmente. In definitiva, quando la tua app raggiunge milioni di utenti, potresti persino decidere di escludere completamente il codice tablet dal codice del telefono, ma generalmente puoi aspettare fino a quando non raggiungi quei pochi milioni di ...

+0

C'è un modo semplice per Android? Ho un ViewModel generico e voglio diverse viste basate su axml che condividono lo stesso ViewModel. – j7nn7k

+0

Mi dispiace, non importa :) Se qualcun altro lo sta cercando: Override 'OnViewModelSet()' – j7nn7k

0

Un altro modo per fare è di andare avanti e creare 2 ViewModels, ma hanno entrambi sottoclasse un abstract ViewModel, come segue:

FirstViewViewModel : BaseViewModel 
SecondViewViewModel : BaseViewModel 

con la corrispondente viste con nome:

FirstView.xaml 
SecondView.xaml 

in questo modo, si è in grado di collocare alcuni comportamenti condivisi in BaseViewMod el, mentre le 2 sottoclassi sono davvero lì solo per soddisfare le convenzioni di visualizzazione di MvvmCross.

0

Recentemente ho iniziato con MvvmCross e sto usando v4.2.1. Sembra che alcuni nomi siano cambiati. Sto usando un ViewModel con le viste separate di iPhone e iPad con il seguente:

[MvxFormFactorSpecific(MvxIosFormFactor.Phone)] 
public class MyIPhoneView : BaseView<MainViewModel> 
{ 
    // iphone specific view ... 
} 

[MvxFormFactorSpecific(MvxIosFormFactor.TallPhone)] 
public class MyTallIPhoneView : BaseView<MainViewModel> 
{ 
    // tall iphone specific view ... 
} 

[MvxFormFactorSpecific(MvxIosFormFactor.Pad)] 
public class MyIPadView : BaseView<MainViewModel> 
{ 
    // ipad specific view ... 
}