如何告诉MVVMLight创建新的视图模型?

时间:2019-02-11 20:32:04

标签: c# wpf mvvm-light

我正在WPF项目中使用MvvmLight,并按照其示例所示设置了视图模型定位器...

public class ViewModelLocator {
  public ViewModelLocator() {
    SimpleIoc.Default.Register<MainWindowViewModel>();
    SimpleIoc.Default.Register<ProductDetailsWindowViewModel>();
  }

  public MainWindowViewModel MainWindowViewModel =>
    SimpleIoc.Default.GetInstance<MainWindowViewModel>();
  public ProductDetailsWindowViewModel ProductDetailsWindowViewModel => 
    SimpleIoc.Default.GetInstance<ProductDetailsWindowViewModel>();
}

我的XAML开头标记中有以下一行...

DataContext="{Binding Source={StaticResource Locator},
    Path=ProductDetailsWindowViewModel}"

这有效,但是定位器始终返回相同的视图模型,即相同的实例,这意味着如果我打开了多个产品详细信息窗口,则它们将共享相同的视图模型。

当我请求一个视图模型时,如何告诉MvvmLight创建一个新的视图模型?

2 个答案:

答案 0 :(得分:2)

  

当我请求一个视图模型时,如何告诉MvvmLight创建一个新的视图模型?

使用GetInstance方法的重载来接受string并将唯一的string值传递给它:

public MainViewModel Main =>
    ServiceLocator.Current.GetInstance<MainViewModel>(System.Guid.NewGuid().ToString());

答案 1 :(得分:1)

我们始终使用Ninject,默认情况下,它似乎可以满足您的要求:-

首先,为Ninject

添加对Nuget包的引用

然后将一个ViewModelLocator类添加到您的项目中,并使用如下代码...

public class ViewModelLocator {
  public IKernel Kernel { get; set; }

  public ViewModelLocator() {
    Kernel = new StandardKernel();
  }

  public MainWindowViewModel MainWindowViewModel =>
    Kernel.Get<MainWindowViewModel>();
  public ProductDetailsWindowViewModel ProductDetailsWindowViewModel =>
    Kernel.Get<ProductDetailsWindowViewModel>();
}

在App.xaml中为定位器添加静态资源,如下所示...

<Application.Resources>
  <viewModels:ViewModelLocator x:Key="Locator" />
</Application.Resources>

确保您的视图模型继承自ViewModelBase ...

public class ProductDetailsWindowViewModel : ViewModelBase
  // ...

然后您的DataContext应该可以正常工作。每个窗口都会获得自己的类实例。

您需要确保在此处进行的一件事是自己清理,否则最终会产生大量的幽灵视图模型。在窗口的“卸载”事件中,将DataContext设置为null ...

private void Window_Closing(object sender, CancelEventArgs e) {
  DataContext = null;
}