0x6Navigation
Basic Navigation
Prism中的Navigation提供了一种类似导航的功能,他可以根据用户的输入,来刷新UI。
先看一个最简单的例子,通过按钮来导航到一个视图,在这里,视图被注册为Navication。
public void Initialize() { _container.RegisterTypeForNavigation(); _container.RegisterTypeForNavigation (); }
Shell 视图中设置两个Button并且绑定下面这个带参数的命令:
public DelegateCommandNavigateCommand { get; private set; } public MainWindowViewModel(IRegionManager regionManager) { _regionManager = regionManager; NavigateCommand = new DelegateCommand (Navigate); } private void Navigate(string navigatePath) { if (navigatePath != null) _regionManager.RequestNavigate("ContentRegion", navigatePath); }
RegionManager通过RequestNavigate方法来获取已经注册的Navigation并且绑定到Region上去。
当需要根据调用结果来处理一些事情,可以使用下面这个方法:
void RequestNavigate(string regionName, string source, ActionnavigationCallback);
当然,上面这个方法是在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在设置为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();