在prism中要實現頁面匯入時傳入參數中比如MyView?param1=abc¶m2=123,如何獲得這些參數呢?這就要實現INavigationAware介面。
上面那個視圖View叫MyView,假設它的ViewModel叫MyViewModel,那個這個ViewModel必須實現INavigationAware介面。
INavigationAware介面源碼
View Code
public interface INavigationAware{bool IsNavigationTarget(NavigationContext navigationContext);void OnNavigatedTo(NavigationContext navigationContext);void OnNavigatedFrom(NavigationContext navigationContext);}
這三個方法都很重要:
- IsNavigationTarget方法:當前的視圖模型是否可以處理請求的導航行為,通常用來指定當前的視圖/模型是否可以重用。例如,一個顯示客戶明細的視圖可以顯示客戶a,客戶b....等的資訊,他們重用同一個視圖。
- OnNavigatedTo方法:當前的頁面被導航到以後發生,這個函數可以用來處理URI的參數。
- OnNavigatedFrom方法:當前的頁面導航到其他頁面的時候發生。
這裡給出一個實現了INavigationAware介面的ViewModel例子:
View Code
1 [Export("MyViewModel ", typeof(MyViewModel ))] 2 [PartCreationPolicy(CreationPolicy.NonShared)] 3 public class MyViewModel : INavigationAware 4 { 5 private IRegionNavigationJournal navigationJournal; 6 7 bool INavigationAware.IsNavigationTarget(NavigationContext navigationContext) 8 { 9 return true;10 }11 12 void INavigationAware.OnNavigatedFrom(NavigationContext navigationContext)13 {14 // Intentionally not implemented.15 }16 17 18 void INavigationAware.OnNavigatedTo(NavigationContext navigationContext)19 {20 var pram1 = navigationContext.Parameters["param1"];21 22 UpdateDataAsync(pram1 );23 24 this.navigationJournal = navigationContext.NavigationService.Journal;25 }26 27 28 29 }
在上面的例子中,OnNavigatedTo方法擷取了URI的參數,當參數發生變化自動重新擷取資料重新整理ViewModel。這個情境可以用在:例如,一個顯示客戶明細的視圖可以顯示客戶a,客戶b....等的資訊,他們重用同一個視圖。當我們navigate導航到URI:MyView?param1=abc¶m2=123的時候,導航到同一個視圖但客戶ID變化,放在URI的參數中傳遞,OnNavigatedTo方法擷取了URI的參數,重用當前視圖,同時重新整理資料。整個過程很清晰。
IConfirmNavigationRequest介面
有些時候當我們導航到其他頁面的時候,需要彈出一個框提示使用者“是否放棄修改?儲存、放棄、取消”,這就需要實現IConfirmNavigationRequest介面。還是上面那個例子,那個ViewModel還要實現IConfirmNavigationRequest介面。這樣這個ViewModel既實現了INavigationAware介面又實現了IConfirmNavigationRequest介面,觸發的順序如下:
- 導航發生的時候,如果目標也實現了IConfirmNavigationRequest介面,那麼先自動調用ConfirmNavigationRequest.
- ViewModel觸發interaction來開啟一個“是否放棄修改?儲存、放棄、取消” 確認的UI。
- 當使用者選擇了"儲存、放棄、取消”以後interaction的callback自動觸發
- 根據使用者的選擇決定是否繼續導航
來一個例子:
View Code
ViewModel實現了IConfirmNavigationRequest介面1 public class ComposeEmailViewModel : NotificationObject, IConfirmNavigationRequest2 {3 private readonly InteractionRequest<Confirmation>4 confirmExitInteractionRequest;5 public ComposeEmailViewModel(IEmailService emailService)6 {7 this.confirmExitInteractionRequest = new8 InteractionRequest<Confirmation>();9 }10 public IInteractionRequest ConfirmExitInteractionRequest11 {12 get { return this.confirmExitInteractionRequest; }13 }14 }XAML定義Interaction<UserControl.Resources><DataTemplate x:Name="ConfirmExitDialogTemplate"><TextBlock HorizontalAlignment="Center" VerticalAlignment="Center"Text="{Binding}"/></DataTemplate></UserControl.Resources><Grid x:Name="LayoutRoot" Background="White"><ei:Interaction.Triggers><prism:InteractionRequestTriggerSourceObject="{Binding ConfirmExitInteractionRequest}"><prism:PopupChildWindowActionContentTemplate="{StaticResource ConfirmExitDialogTemplate}"/></prism:InteractionRequestTrigger></ei:Interaction.Triggers>...使用者確認void IConfirmNavigationRequest.ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback){this.confirmExitInteractionRequest.Raise(new Confirmation {Content = "...", Title = "..."},c => {continuationCallback(c.Confirmed);});}