從PRISM開始學WPF(八)導航Navigation-更新至Prism7.1
0x6Navigation
[7.1updated] Navigation 在wpf中並沒有變化
Basic Navigation
Prism中的Navigation提供了一種類似導航的功能,他可以根據用戶的輸入,來刷新UI。
先看一個最簡單的例子,通過按鈕來導航到一個視圖,在這裏,視圖被註冊為Navication。
7.1中不再使用構造函數註入依賴,而是新增了兩個接口OnInitialized和RegisterTypes,前面region的應用的時候,我們使用的是OnInitialized,導航這他用了RegisterTypes,代碼如下,將view註冊成Navication,並且註冊到容器中:
public void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterForNavigation<ViewA>();
containerRegistry.RegisterForNavigation<ViewB>();
}
Shell 視圖中設置兩個Button並且綁定下面這個帶參數的命令:
public DelegateCommand<string> NavigateCommand { get; private set; } public MainWindowViewModel(IRegionManager regionManager) { _regionManager = regionManager; NavigateCommand = new DelegateCommand<string>(Navigate); } private void Navigate(string navigatePath) { if (navigatePath != null) _regionManager.RequestNavigate("ContentRegion", navigatePath); }
<DockPanel LastChildFill="True"> <StackPanel Orientation="Horizontal" DockPanel.Dock="Top" Margin="5" > <Button Command="{Binding NavigateCommand}" CommandParameter="ViewA" Margin="5">Navigate to View A</Button> <Button Command="{Binding NavigateCommand}" CommandParameter="ViewB" Margin="5">Navigate to View B</Button> </StackPanel> <ContentControl prism:RegionManager.RegionName="ContentRegion" Margin="5" /> </DockPanel>
RegionManager通過RequestNavigate方法來獲取已經註冊的Navigation並且綁定到Region上去。
當需要根據調用結果來處理一些事情,可以使用下面這個方法:
void RequestNavigate(string regionName, string source, Action<NavigationResult> navigationCallback);
當然,上面這個方法是在Shell中調用的,但,有些時候,我們需要View或者ViewModel也參與到Navigation中來,比如當你Request一個Navigation的時候,希望navigation本身顯示一些信息,為此 Prism為我們提供了一個INavigationAware 接口。
//
// Summary:
// Provides a way for objects involved in navigation to be notified of navigation
// activities.
public interface INavigationAware
{
//
// Summary:
// Called to determine if this instance can handle the navigation request.
//
// Parameters:
// navigationContext:
// The navigation context.
//
// Returns:
// true if this instance accepts the navigation request; otherwise, false.
bool IsNavigationTarget(NavigationContext navigationContext);
//
// Summary:
// Called when the implementer is being navigated away from.
//
// Parameters:
// navigationContext:
// The navigation context.
void OnNavigatedFrom(NavigationContext navigationContext);
//
// Summary:
// Called when the implementer has been navigated to.
//
// Parameters:
// navigationContext:
// The navigation context.
void OnNavigatedTo(NavigationContext navigationContext);
}
如果想要Navigation的目標也參與到Navigation的過程當中,只需要讓你的viewmodel實現這個接口,然後在這些方法裏編寫你的代碼就可以了。
IsNavigationTarget方法設置了是否被允許設置為導航的目標,當他的返回值為Fasle的時候,將不會被“導航”到它。
在
19-NavigationParticipation
的例子中,Region的目標是:
<TabControl prism:RegionManager.RegionName="ContentRegion" Margin="5" />
TabControl在設置為Region的時候,加載View時會自動創建Page來存放View,如果“導航”到同一個View他會在Page中找到他,並且顯示出來。但如果IsNavigationTarget返回False的話,就不會顯示之前的Page而是創建了一個新的Page來加載View。
PassingParameters帶參數的導航
使用Navigation的時候,將數據源帶到新的NavigationTarget中去,然後Target應用這些數據。這將使用到navigation的NavigationContext參數:
private void PersonSelected(Person person)
{
var parameters = new NavigationParameters();
parameters.Add("person", person);
if (person != null)
_regionManager.RequestNavigate("PersonDetailsRegion", "PersonDetail", parameters);
}
在Target的OnNavigatedTo方法中使用:
public void OnNavigatedTo(NavigationContext navigationContext)
{
var person = navigationContext.Parameters["person"] as Person;
if (person != null)
SelectedPerson = person;
}
當導航變更的時候你需要一些提示框,需要實現IConfirmNavigationRequest
他有一個ConfirmNavigationRequest方法來進行一些判斷。
在上面的例子中,我們在view之間跳轉的時候,viewA 和viewB是被緩存的,但是有時候,我們跳轉到B的時候想要銷毀A,怎麽來做呢?
在View或ViewModel上實現IRegionMemberLifetime接口,並將KeepAlive屬性的值設置為false。
journal
journal 實現一種類似瀏覽器前進後退按鈕一樣的效果,當一個region 有多個view的時候,他會自動記錄view的加載順序,然後在view之間來回切換。
Prism中是通過IRegionNavigationJournal來實現的,在視圖加載時,講道理,可以無限級前進和後退的,我自己在官方的例子上加了一個視圖也完美運行。
public void OnNavigatedTo(NavigationContext navigationContext)
{
_journal = navigationContext.NavigationService.Journal;
}
然後使用 :
_journal.GoBack();
或者
_journal.GoForward();
從PRISM開始學WPF(八)導航Navigation-更新至Prism7.1