导航到模块中的视图时不调用 OnNavigatedTo
Posted
技术标签:
【中文标题】导航到模块中的视图时不调用 OnNavigatedTo【英文标题】:OnNavigatedTo is not invoked when navigating to a view in module 【发布时间】:2021-06-11 12:14:59 【问题描述】:我是 Prism 新手,正在尝试用它制作一个简单的模块化应用程序(请参阅 full code)。
我实际上是在尝试将参数传递给视图,所以在ModuleAView
的ModuleAViewViewModel
中我正在实现INavigationAware
,这样:
public class ModuleAViewViewModel : BindableBase, INavigationAware
private int passedId;
public int PassedId
get => passedId;
set => SetProperty(ref passedId, value);
// In the following 3 methods, a breakpoint never gets hit.
public bool IsNavigationTarget(NavigationContext navigationContext)
return true;
public void OnNavigatedFrom(NavigationContext navigationContext)
public void OnNavigatedTo(NavigationContext navigationContext)
PassedId = (int)navigationContext.Parameters["Id"];
这是对应的ModuleAView
。
<UserControl x:Class="ModularSample1.Modules.ModuleA.Views.ModuleAView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:ModularSample1.Modules.ModuleA.Views"
xmlns:viewmodels="clr-namespace:ModularSample1.Modules.ModuleA.ViewModels"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<viewmodels:ModuleAViewViewModel x:Key="moduleAViewModel"/>
</UserControl.Resources>
<Grid DataContext="StaticResource moduleAViewModel">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock
Grid.Row="1"
Text="Binding PassedId, StringFormat='Passed Id: 0'"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="34"/>
</Grid>
</UserControl>
实际导航到该视图的 ViewModel 如下所示:
public class MainWindowViewModel : BindableBase
private readonly IRegionManager regionManager;
public MainWindowViewModel(IRegionManager regionManager, IModuleManager moduleManager)
this.regionManager = regionManager;
moduleManager.Run();
Modules = moduleManager.Modules.ToList();
private List<IModuleInfo> modules;
private IModuleInfo selectedModule;
public List<IModuleInfo> Modules
get => modules;
set => SetProperty(ref modules, value);
public IModuleInfo SelectedModule
get => selectedModule;
set
if (SetProperty(ref selectedModule, value))
var Id = new Random().Next(1, 12);
var navigationParameters = new NavigationParameters
"Id", Id
;
regionManager.RequestNavigate(
"SelectedModuleRegion",
$"selectedModule.ModuleNameView",
navigationParameters);
我在这里缺少什么?
【问题讨论】:
【参考方案1】:您在 Resources
中为 ModuleAView
定义视图模型,并通过引用将其设置在子 Grid
上。 Prism 会在 视图本身 上查找 DataContext
以调用实现 INavigationAware
的视图模型,而不是子控件,因此它找不到您的视图模型。来自文档:
在导航期间,Prism 会检查视图是否实现了
INavigationAware
接口;如果是这样,它会在导航期间调用所需的方法。 Prism 还会检查设置为视图的DataContext
的对象是否实现了该接口;如果是,它会在导航期间调用所需的方法。
为了使其工作,直接在ModuleAView
上设置数据上下文并将其从Grid
中删除。
<UserControl x:Class="ModularSample1.Modules.ModuleA.Views.ModuleAView"
...>
<UserControl.DataContext>
<viewmodels:ModuleAViewViewModel/>
</UserControl.DataContext>
<Grid>
<!-- ...grid definitions. -->
</Grid>
</UserControl>
更好的替代方法是从您的ModuleAView
中完全删除手动设置数据上下文,并直接使用ModuleAViewViewModel
注册您的ModuleAView
。 Prism 的导航服务将在导航期间自动解析视图模型并将其分配为数据上下文。
containerRegistry.RegisterForNavigation<ModuleAView, ModuleAViewViewModel>();
您甚至可以通过遵循关于 ViewModelLocator
的视图和视图模型的命名约定来简化这一点,这将用于导航以解析视图的视图模型。
.ViewModels
子命名空间中
视图位于 .Views
子命名空间中
ViewModel 名称与视图名称相对应,并以“ViewModel.
”结尾
您违反了最后一条规则,因此将ModuleAViewViewModel
重命名为ModuleAViewModel
并仅删除数据上下文的手动设置将使Prism 能够自动为您在RegisterForNavigation
注册的视图找到相应的视图模型。
containerRegistry.RegisterForNavigation<ModuleAView>();
【讨论】:
以上是关于导航到模块中的视图时不调用 OnNavigatedTo的主要内容,如果未能解决你的问题,请参考以下文章
视图中的 UITapGesture 时不调用 UIButton 操作
UINavigationContoller interactivePopGestureRecognizer 在导航栏隐藏时不活动
在 UINavigationController 中隐藏导航栏时不向后滑动