背景
對於MVVM 架構的WP程式,一個很關鍵的問題就是導航,以及導航傳參。有過經驗的人很清楚WP導航只能在View中進行,並且導航參數也只能在NavigatedTo等View的事件中擷取,如此我們便不得不在xaml.cs檔案中加上處理,以擷取導航參數然後再通過導航參數構造ViewModel。這個過程很痛苦,因為我們不得不再兩個檔案中來回切換來看我們的邏輯代碼。
那麼接下來我們看下CM作者的厲害之處(必須承認,真的很厲害),
讓我們看下CM架構中導航是什麼樣子的:
不帶參數的情況下:
在ViewModel中定義以下函數:
這兩行涵蓋的很多的資訊,我們首先看下初次看到這幾行時會存在的疑問:
1、navigatoinService是什嗎?
這個成員是如此定義的:
通過代碼我們不難看出,這裡通過依賴注入,MainPageViewModel會得到INavigationService介面類型的對象案例(CM採用容器進行對象的擷取,上文提到我們在Bootstrapper裡面定義了一個Container,此處不做展開,讀者清楚通過此方式得到執行個體即可)。
2、UriFor是做什麼的?
CM的頁面導航是基於ViewModel的導航,自處我們調用UriFor<ActionPractisePageViewModel>,那麼調用了UriFor之後,CM內部會自動定位到工程中定義的ActionPractisePage.xaml中(注意:此處定位基於命名協定,命名規則需匹配APage.xaml->APageViewModel)並自動構建出導航的Uri。
3、Navigate?
這個函數是導航執行的操作,找到ActionPractisePage.xaml後,便可導航到此頁面,並且CM會根據命名協定通過Container再次得到ActionPractisePageViewModel,並將ViewModel自動Binding到View上。
4、其他呢?
事實上很神奇的一件事情就是,我們甚至可以刪除ActionPractisePage.xaml.cs,因為CM內的導航執行後會自動調用ActionPractisePage的InitializeComponent()完成頁面的構造工作。如此我們的工程目錄看起來使這個樣子:-)
5、難道只需要這一行代碼嗎?
前面提到導航後會通過Container得到viewModel的一個案例,因此我們需要在Bootstrapper內配置ActionPractisePageViewModel:
看起來很不錯,通過CM提供的導航我們可以在ViewModel中基於ViewModel進行定位並且導航。調用十分簡潔,流暢介面讓調用也十分容易,不易出錯。