c# - 根据导航区域将参数传递给 ViewModel 构造函数?

标签 c# wpf mvvm prism

我有一个 WPF 应用程序,我尝试逐步迁移到 Prism。当前步骤是 RegionManager 和 NavigationService/Composite UI。

我确实实现了自己的 RegionManager 和 NavigationService 来处理细节,现在我尝试用 Prism RegionManager 替换自己的实现(因为它包含一些很好的功能)这是我尝试解决的问题:

我有一个 TabControl,它能够显示多个彼此没有任何关系的内容(如浏览器)。 TabControl 有一个模板集,它为每个要显示的内容创建一个新区域(所以我有一个 NavigationService 和每个 TabItem 的 Journey)

<userInterface:TabControlHelper.Template>
    <DataTemplate DataType="{x:Type viewModels:ContentViewModel}">
        <ContentControl x:Name="DataContextProxy">
            <ContentControl prism:RegionManager.RegionName="{Binding ElementName=DataContextProxy, Path=DataContext.(viewModels:ContentViewModel.Id)}"
                            prism:RegionManager.RegionManager="{Binding RelativeSource={RelativeSource AncestorType=views:ContentOverview}, Path=DataContext.RegionManager}"
                            Background="{StaticResource BackgroundBrush}"
                            DataContext="{x:Null}" />
        </ContentControl>
    </DataTemplate>
</userInterface:TabControlHelper.Template>

现在当TabControl.SelectedItem更改为新内容我使用以下代码导航到 HomeView:
regionManager.Regions[this.SelectedContent.Id].RequestNavigate("HomeView");

导航工作正常,只是 ViewModel 创建没有:
在我自己的实现中,我处理了 AutoWireViewModel Navigation 内的 AttachedProperty。所以每次我导航到一个 View 时,我都会检查它是否设置了 AutoWireViewModel为真,并且如果我创建了一个 ViewModel,我可以在其中使用区域的名称(即 Content.Id)注入(inject)正确的内容

这就是我卡住的地方。 HomeViewModel需要访问它应该显示的当前内容。我知道可以通过 NavigationContext 注入(inject)内容,但 HomeViewModel实际上应该不在乎IContent在哪里实例来自,它只是取决于它(它不是可选的,所以我更喜欢通过构造函数传递它)。和 HomeView只是需要知道当前内容的众多 View 之一,这意味着如果我通过 NavigationParameters 将内容推送到 ViewModel 中我确实需要每次都获取 Content 的代码,或者我确实需要一些丑陋的基类来处理 NavigationParameter并验证它包含一个 IContent 实例(对我来说这似乎是“远距离行动”)。

如何更改 Prism Navigation 和 AutoWireViewModel 以自动解析正确的 IContent 实例?
它应该使用这样的东西:
IContent targetContent = Container.Resolve<IContentManager>.Contents[this.RegionThatDidInvokeTheNavigation.Name]

还是有更好的方法来实现所需的行为?

最佳答案

我也遇到过类似的问题,如果 prism 稍微修改它的 RegionNavigationService 给我们一个影响 View 模型创建的选项,我会很高兴的(见 https://github.com/PrismLibrary/Prism/issues/367 )。

如果你不喜欢实现 INavigationAware在您的 View 模型上(这意味着您在导航实际发生之前处于未初始化状态),您可以修改 RegionNavigationService.ExecuteNavigation像这样:

[...update journal...]

// Create and set the view model based on the navigation context
var viewAsDependencyObject = view as DependencyObject;
if (viewAsDependencyObject != null)
{
    var createViewModelOnNavigateTo = ViewModelLocator.GetCreateViewModelOnNavigateTo( viewAsDependencyObject );
    if (createViewModelOnNavigateTo)
        ViewModelLocator.Bind( view, _viewModelProvider.CreateViewModel( viewAsDependencyObject, navigationContext ) );
}

[...inform view...]
_viewModelProvider是一项从 NavigationContext 创建 View 模型的服务。 , CreateViewModelOnNavigate是类似于 AutoWireViewModel 的附加属性.

关于c# - 根据导航区域将参数传递给 ViewModel 构造函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34658364/

相关文章:

c# - 如何填充 GridView 异步

asp.net-mvc - ASP.NET MVC 4/MVVM/Web API 的结构是否良好?

c# - 在 div id 上使用 FindControl 时出错

c# - 如何以一种形式发布两个或多个模型?

.net - WPF 与 System.Drawing

c# - 动态添加标签到 DevExpress DXTabControl WPF, MVVM

c# - 在 Ubuntu 20.04 上运行 dotnet 应用程序

c# - 使用同一个程序集多次调用 Assembly.Load(AssemblyName) 有什么缺点?

wpf - 路径上的按钮 IsMouseOver 触发器不起作用

c# - WPF MVVM Datagrid 具有 Combobox 更新 selectedItem 更改上的其他列