2014-01-09 21 views
0

在我的WP8應用程序中,我有MainView引用MainViewModel。 MainView是一個菜單,用戶可以導航到其他視圖來完成一些任務。在使用ShowViewModel時,從MainView導航完美工作。但是,在用戶完成任務時從其他視圖進行導航,使用NavigationService.Navigate(URI)返回到MainView將引發異常「無法找到傳入的mvxviewmodel請求」。mvvmcross:NavigationService.Navigate拋出一個MvxException「無法找到傳入的mvxviewmodelrequest」

爲了避免這種情況的例外,我有構造URI像下面

var req = "{\"ViewModelType\":\"MyApp.Core.ViewModels.MainViewModel, MyApp.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null\",\"ClearTop\":\"true\",\"ParameterValues\":null,\"RequestedBy\":null}"; 
NavigationService.Navigate(new Uri("/MainView.xaml?ApplicationUrl=" + Uri.EscapeDataString(req), UriKind.Relative)); 

有沒有人有更好的方式來使用NavigationService.Navigate?

回答

6

MvvmCross樣本中的大部分導航由MvxAppStart對象或MvxViewModel s啓動。這兩個類從MvxNavigatingObject繼承和使用ShowViewModel方法暴露在那裏 - 看https://github.com/MvvmCross/MvvmCross/blob/v3.1/Cirrious/Cirrious.MvvmCross/ViewModels/MvxNavigatingObject.cs

MvxNavigatingObject,你可以看到MvvmCross路線導航調用IMvxViewDispatcher這在WindowsPhone的是一個非常薄的對象 - 它是所有馬歇爾到UI線程和所有的呼叫,將它們傳遞到IMvxViewPresenter - 見https://github.com/MvvmCross/MvvmCross/blob/v3.1/Cirrious/Cirrious.MvvmCross.WindowsPhone/Views/MvxPhoneViewDispatcher.cs

主講人是Setup創建的對象 - 和默認實現使用IMvxPhoneViewModelRequestTranslator導航呼叫轉換爲基於URI的導航 - 請參閱https://github.com/MvvmCross/MvvmCross/blob/v3.1/Cirrious/Cirrious.MvvmCross.WindowsPhone/Views/MvxPhoneViewPresenter.cs

Silverlight/WindowsPhone然後使用此uri進行導航,創建必要的Xaml頁面,然後在此頁面上調用OnNavigatedTo。作爲交付MvxPhonePagebase.OnNavigatedTo();的一部分,MvvmCross然後調用OnViewCreated擴展方法。如果這個方法檢查已經是一個視圖模型 - 如果沒有一個則嘗試使用URI中的信息來定位一個 - 看https://github.com/MvvmCross/MvvmCross/blob/v3.1/Cirrious/Cirrious.MvvmCross.WindowsPhone/Views/MvxPhoneExtensionMethods.cs


這個解釋記住,如果任何應用程序曾經想從尚未從MvxNavigatingObject繼承的課程啓動MvvmCross導航 - 例如從一些Service或從其他類,則有幾種選擇:

  1. 你可以提供一個墊片對象做導航 - 例如:

    public class MyNavigator : MvxNavigatingObject { 
         public void DoIt() { 
          ShowViewModel<MyViewModel>(); 
         } 
    } 
    
    // used as: 
    var m = new MyNavigator(); 
    m.DoIt(); 
    
  2. 您可以改用國際奧委會找到IMvxViewDispatcherIMvxViewPresenter並且可以調用其Show方法直接

    var request = MvxViewModelRequest<MyViewModel>.GetDefaultRequest(); 
    var presenter = Mvx.Resolve<IMvxViewPresenter>(); 
    presenter.Show(request); 
    
  3. 你可以寫手工代碼它模仿IMvxViewPresenter做什麼 - 完全按照你在您的代碼中 - 儘管使用IMvxPhoneViewModelRequestTranslator.cs來協助生成url可能更「安全」 - 請參閱https://github.com/MvvmCross/MvvmCross/blob/v3.1/Cirrious/Cirrious.MvvmCross.WindowsPhone/Views/IMvxPhoneViewModelRequestTranslator.cs

    var request = MvxViewModelRequest<MyViewModel>.GetDefaultRequest(); 
    var translator = Mvx.Resolve<IMvxPhoneViewModelRequestTranslator>(); 
    var uri = translator.GetXamlUriFor(request); 
    

另外一個選項,View總是有是他們沒有使用標準MvvmCross導航和視圖模型的位置。在WindowsPhone的,你的代碼可以輕鬆地設置視圖模型直接使用你自己喜歡的邏輯:

protected override void OnNavigatedTo(NavigationEventArgs e) 
    { 
     if (ViewModel == null) { 
      ViewModel = // something I locate 
     } 

     // if you are doing your own logic then `base.OnNavigatedTo` isn't really needed in winphone 
     // but I always call it anyway 
     base.OnNavigatedTo(e); 
    } 

或者在WindowsPhone的,你甚至可以使用它是視圖模型定位自己的邏輯不同的基類取代MvxPhonePage。這在WindowsPhone中很容易實現,因爲所有Xaml頁面都具有內置的數據綁定支持。

相關問題