我有一个WPF应用程序,我尝试逐步转移到Prism。当前步骤是RegionManager和NavigationService / Composite UI。
我确实实现了一个自己的RegionManager和NavigationService来处理细节,现在我尝试用Prism RegionManager替换自己的实现(因为它包含一些很好的功能)这里是我试图解决的问题:< / p>
我有一个TabControl,它能够显示多个彼此无关的内容(如浏览器)。 TabControl有一个模板集,为每个要显示的内容创建一个新的区域(所以我有一个NavigationService和每个TabItem的旅程)
<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
AttachedProperty。所以每当我导航到View我检查它是否已将AutoWireViewModel
设置为true,如果我创建了一个ViewModel,我可以使用Region的名称(Content.Id)注入正确的内容
这是我被困的地方。 HomeViewModel
需要访问它应显示的当前内容。我知道可以通过NavigationContext
注入内容,但HomeViewModel
实际上并不关心IContent
实例的来源,它只取决于它(它不是可选的,所以我宁愿在via构造函数中传递它)。 HomeView
只是需要了解当前内容的很多视图中的一个,这意味着如果我通过NavigationParameters
将内容推送到ViewModel中,我需要每次都需要内容的代码,或者我确实需要一些丑陋的基类来处理NavigationParameter
并验证它包含一个IContent实例(对我而言似乎是“远距离行动”)。
如何更改Prism Navigation和AutoWireViewModel以自动解析IContent的正确实例? 它应该使用这样的东西:
IContent targetContent = Container.Resolve<IContentManager>.Contents[this.RegionThatDidInvokeTheNavigation.Name]
或者有更好的方法来实现理想的行为吗?
答案 0 :(得分:2)
我遇到了类似的问题,如果prism稍微修改了它的RegionNavigationService给我们一个影响viewmodel创建的选项,我会很高兴(参见https://github.com/PrismLibrary/Prism/issues/367)。
如果你不想在你的viewmodel上实现INavigationAware
(这意味着你在导航实际发生之前就处于未初始化状态),你可以像这样修改RegionNavigationService.ExecuteNavigation
:< / p>
[...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
创建视图模型的服务,CreateViewModelOnNavigate
是一个类似于AutoWireViewModel
的附加属性。