Prism之导航(Navigation)
一、注册导航
1、注册视图或起别名
public class ModuleAProfile : IModule
{
public void OnInitialized(IContainerProvider containerProvider)
{
}
public void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterForNavigation<ViewA>();
//注册时指定ViewMode
//containerRegistry.RegisterForNavigation<ViewA>("ViewAVM");
}
}
2、注册时指定ViewMode并指定别名
public class ModuleAProfile : IModule
{
public void OnInitialized(IContainerProvider containerProvider)
{
}
public void RegisterTypes(IContainerRegistry containerRegistry)
{
containerRegistry.RegisterForNavigation<ViewA,ViewAViewModel>();
//注册时指定ViewMode并指定别名
//containerRegistry.RegisterForNavigation<ViewA, ViewAViewModel>("ViewAVM");
}
}
二、使用导航
IRegionManager regionManager = …;
regionManager.RequestNavigate("RegionName", "ViewName");
可以注意点, 我们调用了IRegionManager接口的RequestNavigate方法, 并且传递了两个参数:
- RegionName: 该参数为注册的区域名称
- ViewName: 该参数实际为我们上面注册过的导航页, 字符串类型, 对应的是我们注册页面的nameof
三、带参数导航
1、通过F12查看RequestNavigate,可以发现可以传递一个NavigationParameters进去,它是一个键值对的集合
NavigationParameters pairs = new NavigationParameters();
pairs.Add("Keys1", "Hello Prism!");
_regionManage.Regions["ModuleContent"].RequestNavigate(obj,pairs);
2、接着在VM中继承INavigationAware并实现
3、在OnNavigatedTo方法中NavigationContext获取到所传递的参数,通过属性保存并绑定到视图中
public void OnNavigatedTo(NavigationContext navigationContext)
{
if (navigationContext.Parameters.ContainsKey("Keys1"))
{
Content = navigationContext.Parameters.GetValue<string>("Keys1");
}
}
- OnNavigatedTo: 导航完成前, 此处可以传递过来的参数以及是否允许导航等动作的控制。
- IsNavigationTarget: 调用以确定此实例是否可以处理导航请求。否则新建实例
- OnNavigatedFrom: 用于拦截导航,当导航离开当前页时, 类似打开A, 再打开B时, 该方法被触发。
INavigationAware 执行流程
拦截导航请求如果需要更多的功能则可以继承IConfirmNavigationRequest,通过F12发现它派生于INavigationAware,并且有一个自己独有的方法ConfirmNavigationRequest
public void ConfirmNavigationRequest(NavigationContext navigationContext, Action<bool> continuationCallback)
{
bool result = true;
if (MessageBox.Show("确认是否要离开当前模块?","系统提示",MessageBoxButton.YesNo)==MessageBoxResult.No)
{
result = false;
}
continuationCallback(result);
}
效果:
四、上一步/下一步
1、F12查看RequestNavigate,重载方法中有一个参数为Action
我们稍微改一下
2、声明一个IRegionNavigationJournal
private IRegionNavigationJournal journal;
3、在RequestNavigate中加一个Callback参数,获取返回结果,通过这个navigationCallback的上下文中的导航服务获取到Journal并赋值给刚声明的IRegionNavigationJournal
regionManage.Regions["ModuleContent"].RequestNavigate(obj, navigationCallback =>
{
if ((bool)navigationCallback.Result)
{
journal = navigationCallback.Context.NavigationService.Journal;
}
}, pairs);
4、创建两个用于导航的按钮命令
public DelegateCommand BackCommand { get; private set; }
public DelegateCommand NextCommand { get; private set; }
public MainWindowViewModel(IRegionManager regionManager)
{
_regionManage = regionManager;
OpenCommand = new DelegateCommand<string>(OpenMethod);
BackCommand = new DelegateCommand(Back);
NextCommand = new DelegateCommand(Next);
}
5、通过Journal即可调用导航
private void Back()
{
if (journal.CanGoBack)
{
journal.GoBack();
}
}
效果: