如何将多个视图的DataContext设置为ViewModel的一个实例

时间:2017-08-23 20:13:16

标签: c# wpf mvvm prism-6

我正在为我的视图使用ViewModelLocator,它在Bootstrapper中使用以下方法配置:

protected override void ConfigureViewModelLocator()
{
    base.ConfigureViewModelLocator();

    ViewModelLocationProvider.Register<ViewA, ViewABViewModel>();
    ViewModelLocationProvider.Register<ViewB, ViewABViewModel>();
}

它运行正常,但为我的2个视图创建了两个单独的ViewModel实例。 我希望我的两个视图都使用ViewModel的相同实例。

2 个答案:

答案 0 :(得分:1)

检查source code显示默认情况下为每个视图创建新实例的问题:

static Func<Type, object> _defaultViewModelFactory = type => Activator.CreateInstance(type);

Prism允许通常为所有类型或仅特殊类型定义此方法。第二种情况应该是首选。

ViewModelLocationProvider.Register<ViewA, ViewABViewModel>();

仅将View和ViewModel的类型链接在一起,未定义工厂。这意味着为每个View创建了一个新实例。要在多个视图中使用实例,您需要定义工厂方法。创建ViewModel的一个实例

ViewABViewModel vm = new ViewABViewModel();

并通过返回已准备好的实例

来注册Views的工厂方法
ViewModelLocationProvider.Register<ViewA>(() => vm);
ViewModelLocationProvider.Register<ViewB>(() => vm);

Prism现在采用这个实例而不是创建一个新实例。

答案 1 :(得分:1)

您可以将视图模型注册为单例:

protected override void ConfigureViewModelLocator()
{
    base.ConfigureViewModelLocator();

    Container.RegisterType<ViewAViewModel>(new ContainerControlledLifetimeManager()); //<--
    ViewModelLocationProvider.Register<ViewA, ViewABViewModel>();
    ViewModelLocationProvider.Register<ViewB, ViewABViewModel>();
}

或者使用@Fruchtzwerg建议接受工厂的方法重载。