【问题标题】:MvvmCross and complex navigationMvvm交叉和复杂导航
【发布时间】:2014-03-03 08:42:42
【问题描述】:

我很难理解,mvvmcross 导航如何在一些更复杂的情况下工作。让我们以应用程序为例,我们希望使用 mvvmcross 作为基础为 WP7 和 Metro 制作该应用程序。我们创建三个视图模型(FirstViewModel、SecondViewModel、ThirdVIewModel),用一些数据填充它们并使用常规导航在它们之间移动(使用 ShowViewModel() 方法)。到目前为止,这很好用,我们希望在 Windows Phone 设备上进行这种导航,这是三个独立的视图,我们可以来回导航。

现在从 Metro 应用程序的角度来看 - 我们的屏幕要大得多,通常用于横向模式,因此我们决定希望将这三个页面的内容显示为一个页面。

这就是我看到问题的地方 - 因为两个版本的应用程序使用相同的核心和相同的视图模型层次结构 - 似乎不可能同时具有这种行为。从 FirstViewModel 到 SecondViewModel 的导航不适用于 Metro 版本的应用程序,因为我们实际上在第一个屏幕上,我们想要包含来自所有三个视图模型的所有数据。另一方面,我们不能将这三个视图模型放在更大的视图模型中并将其用作单一视图模型,因为这三个单独的视图模型以及常规导航对我们在 Windows Phone 上非常有效。

有没有办法使用 mvvmcross 提供这种非标准导航?如果是这样,是需要覆盖/添加一些简单的代码(我没有看到,也许?),还是相当复杂的东西,需要大量的时间和编码来启用这种功能?

【问题讨论】:

    标签: navigation xamarin mvvmcross


    【解决方案1】:

    MvvmCross 有不同的方法来改变它的默认机制。 一个好的起点是 Wiki:https://github.com/MvvmCross/MvvmCross/wiki/Customising-using-App-and-Setup

    关于你的例子:

    我的一个想法是创建一个 MainViewModel,其中包含 WindowStore 应用程序的所有三个视图模型。

    您仍然可以在 Core 项目中拥有 MainViewModel,即使它仅由 Windows 应用商店应用使用。您可能还想稍后将它用于 Android 或 iOS 平板电脑应用:

    public class MainViewModel : MvxViewModel
    {
        public FirstViewModel First { get; private set; }
        public SecondViewModel Second { get; private set; }
        public ThirdViewModel Third { get; private set; }
    
        public MainViewModel()
        {
              this.First = new FirstViewModel();
              this.Second = new SecondViewModel();
              this.Third = new ThirdViewModel();
         }
    }
    

    接下来,根据平台,您需要导航到 MainViewModel 或 FirstViewModel

    在 MvvmCross 中有几种方法可以做到这一点。

    一个选项是有一个 CustomAppStart,它根据平台导航到初始视图模型。

    在核心库中:

     public class CustomAppStart
            : MvxNavigatingObject
            , IMvxAppStart
        {
            public void Start(object hint = null)
            {
               var platform == GetRunningPlatform();
               switch(platform)
               { 
                  case Platform.WinStore:
                       ShowViewModel<MainViewModel>();
                       break;
                  case Platform.WinPhone:
                       ShowViewModel<FirstViewModel>();
                       break;               
                  ...    
            }
        }
    

    为了检测应用程序在哪个平台上运行,也有几种方法可以做到这一点。 检查How can I detect the platform at runtime using MvvMCross? 或 MvvmLight 是如何做到的:http://mvvmlight.codeplex.com/SourceControl/network/forks/onovotny/MvvmLightPortable/changeset/view/f356af74426f#GalaSoft.MvvmLight/Portable/GalaSoft.MvvmLight/Helpers/DesignerPlatformLibrary.cs

    另一个想法是在每个平台上都有单独的 WinPhoneAppStart 和 WinStoreAppStart。请注意,自定义应用启动(IMvxAppStart)需要在创建 IMvxApplication 之前注册。

    在 Windows 应用商店应用中:

    public class WinStoreAppStart : MvxNavigatingObject, IMvxAppStart
    {
        public void Start(object hint = null)
        {
           ShowViewModel<MainViewModel>();   
        }  
    }
    
    public class Setup : MvxStoreSetup
    { 
         protected override IMvxApplication CreateApp()
         {
             Mvx.RegisterType(typeof(IMvxAppStart), typeof(WinStoreAppStart));
             return new Core.App();
         } 
    }
    

    唷,我希望这对你有帮助。如果您需要更多信息,请告诉我。

    编辑:

    如果这 3 个页面不代表起始主页,那么我的一个想法是使用自定义演示者:https://github.com/MvvmCross/MvvmCross/wiki/Customising-using-App-and-Setup#wiki-custom-presenters

    在 WinStore 应用程序中,您可以捕捉到 FirstViewModel 的导航并改为创建 MainViewModel。

    另一个想法:

    您可以拥有一个依赖于平台的控制器来实现视图模型导航。

    【讨论】:

    • 感谢您的快速回复!自定义 AppStart 或单独的应用程序启动可以解决问题,但只能在应用程序的开头(应用程序启动:)。如果我稍后在导航期间想要类似的行为怎么办,假设在移动设备上的第 7、8 和 9 页之间进行单独导航,而在 Metro 应用程序上使用相同的 Core 项目导航到包含内容 7,8 和 9 的“大页面” ?
    • 我编辑我的回复以包含这个场景。如果您认为这是您需要的,请标记为答案。
    【解决方案2】:

    当然可以,尽管您需要编写一些自定义类。如果您为每个平台编写自定义演示器,您可以使用区域的概念,您的视图可以在其中指示它们希望显示的区域,以便在调用 ShowViewModel 时,您的自定义演示器可以检查适当的视图是否请求特定区域并根据需要进行处理。

    在自定义演示者上查看 Stuart Lodges n+1。另外谷歌“MVVMCross region Presenters”。你应该找到一些有用的材料。

    干杯, 特里斯坦

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-12-27
      • 1970-01-01
      • 2017-12-20
      • 1970-01-01
      • 2015-06-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多