2012-04-24 16 views
7

He estado usando MvvmCross en un proyecto móvil multiplataforma y tengo 2 vistas diferentes en un proyecto MonoTouch que utilizan el mismo modelo de vista compartido y no estoy seguro de cómo estructurar mi código para navegar a diferentes vistas usando el mismo modelo de vista en MvvmCross.MvvmCross - Modelos de vista compartidos para múltiples vistas

Respuesta

11

La convención predeterminada utilizada por la plataforma MvvmCross es registrar automáticamente todas las vistas mediante la reflexión.

Esto se hace en la clase de instalación de base - en 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); 
     } 
    } 

donde GetViewModelViewLookup devuelve un diccionario de tipo de modelo de vista a vista de tipo:

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

En universales iPad/iPhone Apps que haces ocasionalmente desea incluir múltiples vistas para cada modelo de vista, usando una vista en el iPad y una vista en el iPhone.

Para hacer esto, hay ahora (literalmente justo ahora!) Algunos atributos disponibles para marcar sus puntos de vista como "no convencional" - estos son:

El último de ellos es, probablemente, lo que quiere en este caso - podría implementar conmutación sencilla iPhone/iPad para un MainViewModel utilizando dos vistas declarado como:

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

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

Alternativamente, si desea una configuración muy personalizada, puede anular todo el comportamiento 'basado en convenciones': puede implementar su propia anulación de GetViewModelViewLookup - p.:

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 que eventualmente puede decidir que necesita ViewModels adicionales, así como dictamen de la aplicación IPAD - IPAD tiene, después de todo, una mucho más grande de la pantalla - en este caso, se puede agrégalos manualmente. En definitiva, cuando su aplicación llegue a unos pocos millones de usuarios, incluso puede decidir desviar completamente el código de la tableta del código del teléfono, pero eso generalmente puede esperar hasta llegar a esa marca de unos pocos millones ...

+0

¿Hay una manera simple para Android? Tengo un ViewModel genérico y quiero diferentes vistas basadas en axml que compartan el mismo ViewModel. – j7nn7k

+0

Lo siento, no importa :) Si alguien más está buscando eso: Anular 'OnViewModelSet()' – j7nn7k

0

Otra forma de hacerlo es seguir adelante y crear 2 ViewModels, pero tenerlos a ambos subclasificar modelo de vista abstracto, de la siguiente manera:

FirstViewViewModel : BaseViewModel 
SecondViewViewModel : BaseViewModel 

con las vistas correspondientes con nombre:

FirstView.xaml 
SecondView.xaml 

de esta manera, usted es capaz de colocar un comportamiento compartido en BaseViewMod el, mientras que las 2 subclases realmente están ahí para satisfacer las convenciones de búsqueda de MvvmCross.

0

Recientemente comencé con MvvmCross y estoy usando v4.2.1. Parece que algunos nombres han cambiado. Estoy usando un ViewModel con vistas separadas de iPhone y iPad con lo siguiente:

[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 ... 
} 
Cuestiones relacionadas