C# 是否根据导航区域将参数传递到ViewModel构造函数?

C# 是否根据导航区域将参数传递到ViewModel构造函数?,c#,wpf,mvvm,prism,C#,Wpf,Mvvm,Prism,我有一个WPF应用程序,我试图一步一步地移动到Prism。当前步骤是RegionManager和NavigationService/CompositeUI 我确实实现了自己的RegionManager和NavigationService来处理细节,现在我尝试用Prism RegionManager替换自己的实现(因为它包含一些功能,这会很好),下面是我尝试解决的问题: 我有一个TabControl,它能够显示彼此无关的多个内容(如浏览器)。TabControl有一个模板集,为每个要显示的内容创建

我有一个WPF应用程序,我试图一步一步地移动到Prism。当前步骤是RegionManager和NavigationService/CompositeUI

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

我有一个TabControl,它能够显示彼此无关的多个内容(如浏览器)。TabControl有一个模板集,为每个要显示的内容创建一个新区域(因此我为每个TabItem提供了导航服务和旅程)

导航工作正常,只是ViewModel创建无法: 在我自己的实现中,我处理了导航中的
AutoWireViewModel
AttachedProperty。因此,每次我导航到一个视图时,我都会检查它是否已将
AutoWireViewModel
设置为true,以及是否创建了一个视图模型,在该视图模型中,我能够使用区域名称(即Content.Id)插入正确的内容

这就是我被困的地方。
HomeViewModel
需要访问它应该显示的当前内容。我知道可以通过
NavigationContext
注入内容,但是
HomeViewModel
实际上不应该关心
IContent
实例来自何处,它只是取决于它(它不是可选的,所以我更喜欢通过构造函数传递它)。而
HomeView
只是许多需要了解当前内容的视图中的一个,这意味着如果我通过
NavigationParameters
将内容推送到ViewModel中,我确实需要每次获取内容的代码,或者我确实需要一些丑陋的基类来处理
NavigationParameter
,并验证它是否包含IContent实例(对我来说,这就像是“远处的动作”)

如何更改Prism Navigation和AutoWireViewModel以自动解析IContent的正确实例? 它应该使用如下内容:

IContent targetContent = Container.Resolve<IContentManager>.Contents[this.RegionThatDidInvokeTheNavigation.Name]
[...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...]
IContent targetContent=Container.Resolve.Contents[this.regionAtDidInvokeTheNavigation.Name]

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

我也遇到过类似的问题,我希望prism稍微修改其RegionNavigationService,让我们可以选择影响viewmodel的创建(请参阅)

如果您不想在viewmodel上实现
INavigationAware
(这意味着您在导航实际发生之前处于非斜体状态),您可以修改
RegionNavigationService.ExecuteNavigation
,如下所示:

IContent targetContent = Container.Resolve<IContentManager>.Contents[this.RegionThatDidInvokeTheNavigation.Name]
[...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...]

\u viewModelProvider
是一项从
NavigationContext
创建ViewModel的服务,
CreateViewModelOnNavigate
是一个类似于
AutoWireViewModel

的附加属性。谢谢,我已经考虑过更改prism库,但我更愿意在不更改库的情况下解决这个问题(因为prism有很好的文档记录)也许我会花时间创建一个pull请求,以一种开放的方式将功能注入prism(类似于创建ViewModel所使用的每个区域的子容器)