缺少 Prism 7 UWP 导航返回参数
Prism 7 UWP Navigation Back Parameters Missing
给定一个具有三个视图和相应视图模型的 Prism 7 UWP 应用程序:
containerRegistry.RegisterForNavigation<BlankPage1, BlankPage1ViewModel>();
containerRegistry.RegisterForNavigation<BlankPage2, BlankPage2ViewModel>();
containerRegistry.RegisterForNavigation<BlankPage3, BlankPage3ViewModel>();
如果我们从 BlankPage1 导航到 BlankPage2 并传递一个参数(从 ViewModel1 的命令中):
public virtual DelegateCommand GoToPage2Command => new DelegateCommand(GoToPage2);
public virtual async void GoToPage2() {
await NavigationService.NavigateAsync("BlankPage2", null, ("param", 5678));
}
在 OnNavigatedToAsync
覆盖 BlankPage2ViewModel
中,参数被正确传入。
现在,如果我们通过命令从 BlankPage2ViewModel
导航到 BlankPage3ViewModel
,并传递另一个参数
public virtual DelegateCommand GoToPage3Command => new DelegateCommand(GoToPage3);
public virtual async void GoToPage3() {
await NavigationService.NavigateAsync("BlankPage3", null, ("param", 1234));
}
再次成功,参数值 1234
被传递给 BlankPage3ViewModel
。
但是现在如果我们导航回 BlankPage2ViewModel
:
await NavigationService.GoBackAsync();
没有参数传回 BlankPage2ViewModel
的 OnNavigatedToAsync
覆盖。我们当然希望看到参数值 5678
?
注意:我们还在每个视图中将 NavigationCacheMode
设置为 Required
。
关于类似问题的 question asked over on the MSDN forums 的回答指出:
If you use Frame.Navigate to navigate to the same page, your PageA won't be reinstanciated but the OnNavigatedTo method will be called with the new parameters.
That way, you can change the information displayed on the page (even play some transition if needed); and as an added bonus the Frame history does keep your previous PageA parameters, allowing you to call Frame.GoBack to return to the previous PageA state.
这是 Prism 的设计,没有传回任何参数还是潜在的错误?
正如@Bite所说,一般的UWP项目是没有问题的。当你调用Frame.Navigate(typeof(page), "params");
方法在不同页面之间导航和调用Frame.GoBack()
方法返回上一页时,参数仍然存在。
既然你用的是棱镜的导航服务,那里面应该有一些不一样的地方。如果想知道详细原因,需要调试其Prism源码,了解其导航服务的原理。
这里,我也对它的导航服务很感兴趣,所以花时间研究了一下它的源码。导航服务的核心应该在NavigationService.cs and FrameFacade.cs.
你可以看到它最终会调用 _frame.Navigate() 方法从一个页面导航到另一个页面。
var parameter = pageNavInfo.QueryString;
return _frame.Navigate(
sourcePageType: pageNavInfo.View,
parameter: parameter,
infoOverride: infoOverride);
_frame
对象实际上是一个通用的 UWP 内置 Frame Class type. So, in general, the navigation parameters should be there when you call _frame.GoBack() 返回上一页。
但是,如果你添加一些断点来调试它,你会看到在上面的_frame.Navigate(sourcePageType: pageNavInfo.View,parameter:parameter,infoOverride: infoOverride);
代码块中参数的值总是null
。这就是为什么在调用GoBack()
方法时总是获取不到导航参数的原因。这是因为它总是将 null
作为参数传递给 _frame.Navigate
方法。它已经实现了自己的 NavigationParameters。您传递给 _navigationService.NavigateAsync()
方法的所有参数都应该在“_external”参数中。
所以,我已经告诉你原因了。我不能说这是设计使然或潜在问题。也许,他们在调用'GoBack()'时没有考虑历史导航参数method.You可以将您的问题提交给Github issue,看看官方是否有解决方法。或者如果你对它感兴趣,你可以尝试更改它的源代码并为你编译你自己的自定义版本。
给定一个具有三个视图和相应视图模型的 Prism 7 UWP 应用程序:
containerRegistry.RegisterForNavigation<BlankPage1, BlankPage1ViewModel>();
containerRegistry.RegisterForNavigation<BlankPage2, BlankPage2ViewModel>();
containerRegistry.RegisterForNavigation<BlankPage3, BlankPage3ViewModel>();
如果我们从 BlankPage1 导航到 BlankPage2 并传递一个参数(从 ViewModel1 的命令中):
public virtual DelegateCommand GoToPage2Command => new DelegateCommand(GoToPage2);
public virtual async void GoToPage2() {
await NavigationService.NavigateAsync("BlankPage2", null, ("param", 5678));
}
在 OnNavigatedToAsync
覆盖 BlankPage2ViewModel
中,参数被正确传入。
现在,如果我们通过命令从 BlankPage2ViewModel
导航到 BlankPage3ViewModel
,并传递另一个参数
public virtual DelegateCommand GoToPage3Command => new DelegateCommand(GoToPage3);
public virtual async void GoToPage3() {
await NavigationService.NavigateAsync("BlankPage3", null, ("param", 1234));
}
再次成功,参数值 1234
被传递给 BlankPage3ViewModel
。
但是现在如果我们导航回 BlankPage2ViewModel
:
await NavigationService.GoBackAsync();
没有参数传回 BlankPage2ViewModel
的 OnNavigatedToAsync
覆盖。我们当然希望看到参数值 5678
?
注意:我们还在每个视图中将 NavigationCacheMode
设置为 Required
。
关于类似问题的 question asked over on the MSDN forums 的回答指出:
If you use Frame.Navigate to navigate to the same page, your PageA won't be reinstanciated but the OnNavigatedTo method will be called with the new parameters.
That way, you can change the information displayed on the page (even play some transition if needed); and as an added bonus the Frame history does keep your previous PageA parameters, allowing you to call Frame.GoBack to return to the previous PageA state.
这是 Prism 的设计,没有传回任何参数还是潜在的错误?
正如@Bite所说,一般的UWP项目是没有问题的。当你调用Frame.Navigate(typeof(page), "params");
方法在不同页面之间导航和调用Frame.GoBack()
方法返回上一页时,参数仍然存在。
既然你用的是棱镜的导航服务,那里面应该有一些不一样的地方。如果想知道详细原因,需要调试其Prism源码,了解其导航服务的原理。
这里,我也对它的导航服务很感兴趣,所以花时间研究了一下它的源码。导航服务的核心应该在NavigationService.cs and FrameFacade.cs.
你可以看到它最终会调用 _frame.Navigate() 方法从一个页面导航到另一个页面。
var parameter = pageNavInfo.QueryString;
return _frame.Navigate(
sourcePageType: pageNavInfo.View,
parameter: parameter,
infoOverride: infoOverride);
_frame
对象实际上是一个通用的 UWP 内置 Frame Class type. So, in general, the navigation parameters should be there when you call _frame.GoBack() 返回上一页。
但是,如果你添加一些断点来调试它,你会看到在上面的_frame.Navigate(sourcePageType: pageNavInfo.View,parameter:parameter,infoOverride: infoOverride);
代码块中参数的值总是null
。这就是为什么在调用GoBack()
方法时总是获取不到导航参数的原因。这是因为它总是将 null
作为参数传递给 _frame.Navigate
方法。它已经实现了自己的 NavigationParameters。您传递给 _navigationService.NavigateAsync()
方法的所有参数都应该在“_external”参数中。
所以,我已经告诉你原因了。我不能说这是设计使然或潜在问题。也许,他们在调用'GoBack()'时没有考虑历史导航参数method.You可以将您的问题提交给Github issue,看看官方是否有解决方法。或者如果你对它感兴趣,你可以尝试更改它的源代码并为你编译你自己的自定义版本。