2012-04-24 36 views
7

我一直在跨平台移动项目中使用MvvmCross,并且在使用相同共享视图模型的MonoTouch项目中拥有2个不同视图,并且不知道如何去构建我的代码以导航到在MvvmCross中使用相同的视图模型的不同视图。MvvmCross - 为多个视图共享视图模型

回答

11

MvvmCross平台使用的默认约定是使用反射自动注册所有视图。

这是在基础设置类来完成 - 在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); 
     } 
    } 

其中GetViewModelViewLookup返回视图模型类型的字典来查看方式:

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

在通用的iPad/iPhone应用程序,你做偶尔想要为每个视图模型包含多个视图 - 使用iPad中的一个视图和iPhone中的一个视图。

要做到这一点,现在(从字面上刚才!)一些可用来标记你的意见为“非常规”的属性 - 它们是:

最后的这些属性可能是你在这种情况下,想要的东西 - 你可以实现简单的iPhone/iPad的切换使用两种意见MainViewModel声明如下:

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

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

或者,如果您需要非常自定义的配置,则可以覆盖所有'基于约定'的行为 - 您可以实施自己的替代GetViewModelViewLookup - 例如:

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

,最终你可能会认为你需要额外的ViewModels以及用于iPad的应用程序视图 - iPad的了,毕竟,一个更大的屏幕 - 在这种情况下,你可以手动添加它们。最终,当您的应用触及几百万用户时,您甚至可能决定将平板电脑代码彻底分离出电话代码 - 但通常可以等到您达到几百万分钟的时候...

+0

Android有没有简单的方法?我有一个通用的ViewModel,并希望不同的基于axml的视图共享相同的ViewModel。 – j7nn7k 2015-02-21 19:45:45

+0

对不起,不知道:)如果别人正在找那个:Overview'OnViewModelSet()' – j7nn7k 2015-02-21 19:57:16

0

另一种方法它是先走,并创建2周的ViewModels,但让他们既继承一个抽象的视图模型,如下:

FirstViewViewModel : BaseViewModel 
SecondViewViewModel : BaseViewModel 

使用命名相应的视图:

FirstView.xaml 
SecondView.xaml 

这种方式,你能够把一些共享行为在BaseViewMod el,而2个子类真的只是为了满足MvvmCross的视图获取约定。

0

我最近开始使用MvvmCross,我正在使用v4.2.1。看来有些名字已经改变了。我正在使用一个ViewModel,具有以下独立的iPhone和iPad视图:

[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 ... 
} 
相关问题