2014-03-03 101 views
1

我很難理解,mvvmcross導航如何在一些更復雜的情況下工作。我們來開發應用程序,我們希望使用mvvmcross作爲基礎,爲WP7和Metro創建應用程序。我們創建三個視圖模型(FirstViewModel,SecondViewModel,ThirdVIewModel),用一些數據填充它們並使用常規導航在它們之間移動(使用ShowViewModel()方法)。到目前爲止,這樣做效果很好,我們希望在Windows Phone設備上使用這種導航,這是三種不同的視圖,我們可以來回導航。MvvmCross和複雜導航

現在從Metro應用程序的角度來看 - 我們有更大的屏幕,通常用於lanscape模式,所以我們決定我們希望這三個頁面的內容顯示爲一個單一頁面。

這裏是我看到的問題 - 因爲這兩個版本的應用程序使用相同的核心和相同的視圖模型層次結構 - 似乎不可能同時具有這種行爲。從FirstViewModel到SecondViewModel的導航不適用於Metro版本的應用程序,因爲我們實際上是在第一個屏幕上,我們想要包含來自所有三個視圖模型的所有數據。另一方面,我們無法將這三種視圖模型放在較大的視圖模型中,並將其用作單視圖模型,因爲這三種單獨的視圖模型以及常規導航對於Windows Phone上的我們非常適用。

有沒有辦法使用mvvmcross提供這樣的非標準導航?如果是這樣,是否需要覆蓋/添加一些簡單的代碼(我沒有看到,也許?),或者相當複雜的東西,需要大量的時間和編碼來啓用這種功能?

回答

1

是的,雖然你會需要寫一些自定義類。如果您爲每個平臺編寫自定義演示者,則可以使用視圖可以指示他們希望顯示哪個區域的區域概念,以便在調用ShowViewModel時,您的自定義演示者可以檢查相應視圖是否請求了特定區域並根據需要進行處理。

查看Stuart Lodges n + 1上的自定義演示者。此外谷歌「MVVMCross地區主持人」。你應該找到一些有用的材料。

乾杯, 特里斯坦

2

MvvmCross有不同的方法來改變其默認的機制。 一個良好的開始是在Wiki:https://github.com/MvvmCross/MvvmCross/wiki/Customising-using-App-and-Setup

關於你提到的例子:

一個想法我已經是創建一個包含所有三個視圖模型的WindowStore應用一個MainViewModel。

即使僅由Windows應用商店應用程序使用,仍可以在Core項目中使用MainViewModel。您可能希望將來再次使用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 Store應用:

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。

另一種想法:

您可以擁有一個實現視圖模型導航的平臺相關控制器。

+0

感謝您的快速回復!自定義AppStart或單獨的應用程序啓動會做的伎倆,但只在應用程序的開始(應用程序啓動:)。如果在導航過程中稍後需要類似的行爲,那麼我們假設在移動設備上的頁面7,8和9與單個導航之間單獨導航到使用相同Core項目的metro應用中包含內容7,8和9的「大頁面」 ? – user3373981

+0

我編輯我的回覆以包括這種情況。如果您認爲這是您需要的,請標記爲答案。 –