windows-phone-7 - MvvmCross - 共享多个 View 的 View 模型

标签 windows-phone-7 xamarin.ios xamarin.android mvvmcross

我一直在跨平台移动项目上使用 MvvmCross,并且在 MonoTouch 项目中有 2 个不同的 View ,它们使用相同的共享 View 模型,但不确定如何构建我的代码以使用 MvvmCross 中的相同 View 模型导航到不同的 View 。

最佳答案

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

这是在基本 Setup 类中完成的 - 在 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返回一个 ViewModel 类型的字典到 View 类型:
    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 应用程序中,您有时确实希望为每个 View 模型包含多个 View - 在 iPad 中使用一个 View ,在 iPhone 中使用一个 View 。

要做到这一点,现在(字面意思是刚刚!)一些属性可用于将您的观点标记为“非常规”——这些是:
  • MvxUnconventionalViewAttribute
  • 用它来标记你的 View 不应该被包含在约定中
  • https://github.com/slodge/MvvmCross/blob/master/Cirrious/Cirrious.MvvmCross/Views/Attributes/MvxUnconventionalViewAttribute.cs
  • MvxConditionalConventionalViewAttribute
  • 抽象属性 - 覆盖它以提供您自己的包含/排除的自定义逻辑
  • https://github.com/slodge/MvvmCross/blob/master/Cirrious/Cirrious.MvvmCross/Views/Attributes/MvxConditionalConventionalViewAttribute.cs
  • MvxFormFactorSpecificViewAttribute
  • 仅限 iOS/Touch
  • 当且仅当检测到的 iPhone 外形与当前设备匹配时,一个包含 View 的属性
  • https://github.com/slodge/MvvmCross/blob/master/Cirrious/Cirrious.MvvmCross/Touch/Views/Attributes/MvxFormFactorSpecificViewAttribute.cs

  • 在这种情况下,最后一个可能是您想要的 - 您可以使用声明如下的两个 View 为 MainViewModel 实现简单的 iPhone/iPad 切换:
    [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) },
            };
        }
    }
    

    请注意,最终您可能会决定需要额外的 ViewModel 以及 iPad 应用程序的 View - 毕竟 iPad 有一个更大的屏幕 - 在这种情况下,您可以手动添加它们。最终,当您的应用达到几百万用户时,您甚至可能决定将平板电脑代码完全从电话代码中分离出来——但这通常可以等到您达到几百万大关...

    关于windows-phone-7 - MvvmCross - 共享多个 View 的 View 模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10297260/

    相关文章:

    Android NDK - 在 Visual Studio 中添加更多目标 API 级别

    c# - 没有互联网的移动通知(仅限本地网络)

    c# - 按下后退键的动画

    internet-explorer - 防止在 Windows Phone 7 的 IE 中滚动

    c# - Canvas 作为 ListBox ItemTemplate

    ios - 包标识符构建错误 xamarin 形成 ios 和 ios 扩展项目

    c# - 等待异步操作完成

    c# - 如何使用 Xamarin iOS 在 MugenMvvm 中使用自定义控件绑定(bind)到事件

    c# - Xamarin.Essentials Share.RequestAsync() 不适用于 iOS

    c# - 在 C# 中动态创建 Android 控件