Wpf Prism 6.3:使用不同的视图模型重用视图';s

Wpf Prism 6.3:使用不同的视图模型重用视图';s,wpf,prism,Wpf,Prism,我的场景是使用两个完全独立的视图模型重用视图 例如,您可以认为通用列表视图在某处显示苹果,在其他地方显示汽车。没关系 在Prism.Forms for Xamarin中,我可以将视图与这样的视图模型粘合在一起 Container.RegisterTypeForNavigation<PageA, ViewModelA>("PageA1"); Container.RegisterTypeForNavigation<PageA, ViewModelB>("PageA2");

我的场景是使用两个完全独立的视图模型重用视图

例如,您可以认为通用列表视图在某处显示苹果,在其他地方显示汽车。没关系

在Prism.Forms for Xamarin中,我可以将视图与这样的视图模型粘合在一起

 Container.RegisterTypeForNavigation<PageA, ViewModelA>("PageA1");
 Container.RegisterTypeForNavigation<PageA, ViewModelB>("PageA2");
Container.RegisterTypeForNavigation(“PageA1”);
容器。导航注册类型(“PageA2”);

我在Prism WPF中找不到类似的产品,有人能帮我吗

@AdamVincent发布的链接和“缺失”方法对于使用ViewModelLocationProvider的常规视图/视图模型导航非常有用。但是,当尝试为同一视图使用两个视图模型时,它们不起作用。这是因为在扩展方法内部有一个调用,该调用将viewmodel注册到视图,以供ViewModelLocationProvider使用

private static IUnityContainer RegisterTypeForNavigationWithViewModel<TViewModel>(this IUnityContainer container, Type viewType, string name)
{
    if (string.IsNullOrWhiteSpace(name))
        name = viewType.Name;

    ViewModelLocationProvider.Register(viewType.ToString(), typeof(TViewModel));

    return container.RegisterTypeForNavigation(viewType, name);
}
私有静态IUnityContainer注册表类型ForNavigationWithViewModel(此IUnityContainer容器,类型viewType,字符串名称)
{
if(string.IsNullOrWhiteSpace(name))
name=viewType.name;
ViewModelLocationProvider.Register(viewType.ToString(),typeof(TViewModel));
返回container.RegisterTypeForNavigation(视图类型、名称);
}
在内部,ViewModelLocationProvider.Register使用字典存储视图模型和视图之间的关联。这意味着,将两个视图模型注册到同一视图时,第二个视图模型将覆盖第一个视图模型

Container.RegisterTypeForNavigation<PageA, ViewModelA>("PageA1");
Container.RegisterTypeForNavigation<PageA, ViewModelB>("PageA2");
Container.RegisterTypeForNavigation(“PageA1”);
容器。导航注册类型(“PageA2”);
因此,使用上述方法,当使用ViewModelLocationProvider时,它将始终创建ViewModelB的实例,因为它是最后一个注册的实例

另外,下一行调用RegisterTypeForNavigation,它本身最终调用Container.RegisterType,它只传递viewType

为了解决这个问题,我使用注入属性以不同的方式处理它。我使用以下方法将viewmodel绑定到视图

private void BindViewModelToView<TView,TViewModel>(string name)
{
    if (!Container.IsRegistered<TViewModel>())
    {
        Container.RegisterType<TViewModel>();
    }

    Container.RegisterType<TView, TViewModel>(name,new InjectionProperty("DataContext", new ResolvedParameter<TViewModel>()));
}
private void BindViewModelToView(字符串名称)
{
如果(!Container.IsRegistered())
{
Container.RegisterType();
}
RegisterType(名称,new InjectionProperty(“DataContext”,new ResolvedParameter());
}
我们知道每个视图都有一个DataContext属性,因此Injection属性将把viewmodel直接注入视图的DataContect中

注册viewmodels时,您将使用以下调用,而不是使用RegisterTypeForNavigation:

BindViewModelToView<PageA,ViewModelA>("ViewModelA");
BindViewModelToView<PageA,ViewModelB>("ViewModelB");
BindViewModelToView(“ViewModelA”);
BindViewModelToView(“ViewModelB”);
为了创建视图,我已经有了一个方法,可以使用该方法将适当的视图注入到我的区域中,并使用viewname作为键来获得正确的viewmodel实例

private object LoadViewIntoRegion<TViewType>(IRegion region, string name)
{
    object view = region.GetView(name);
    if (view == null)
    {
        view = _container.Resolve<TViewType>(name);     
        if (view is null)
        {
            view = _container.Resolve<TViewType>();
        }
        region.Add(view, name);
    }
    return view;
}
私有对象LoadViewIntoRegion(IRegion区域,字符串名称)
{
对象视图=region.GetView(名称);
如果(视图==null)
{
视图=_container.Resolve(名称);
如果(视图为空)
{
视图=_container.Resolve();
}
region.Add(视图、名称);
}
返回视图;
}
我只是打电话给你

var view = LoadViewintoRegion<PageA>(region,"ViewModelA");
var view=LoadViewintoRegion(region,“ViewModelA”);

var view=LoadViewintoRegion(region,“ViewModelB”);

因此,对于普通的单视图/视图模型,我使用ViewModelLocationProvider.AutoWireViewModel属性,如果我有多个视图模型,我使用这种替代方法。

对此没有答案,但完全相关,这是一种有趣的方法。这个在Xamarin.Forms中但不在WPF中的功能实际上已经从Xamarin.Forms中删除。如果您对保留提供的强类型感兴趣,您可以修改
RegisterTypeForNavigation
扩展方法,并在WPF应用程序中进行添加。谢谢。该链接非常有用。如果您使用的是视图优先导航,您可以使用
prism:ViewModelLocator.AutoWireViewModel
属性自动连接视图模型。我想您误解了这个问题:我有一个视图和两个视图模型,但我无法在此处自动连接视图。那么,对于Xamarin表单,这种方法也会一样吗?
var view = LoadViewintoRegion<PageA>(region,"ViewModelB");