【问题标题】:How to tell MVVMLight create a new view model?如何告诉 MVVMLight 创建一个新的视图模型?
【发布时间】:2019-02-11 20:32:03
【问题描述】:

我在 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 创建一个新的视图模型?

【问题讨论】:

    标签: c# wpf mvvm-light


    【解决方案1】:

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

    使用接受stringGetInstance 方法的重载并向其传递唯一的string 值:

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

    【讨论】:

    • 这也很好用。不过,我将开始使用 Ninject。谢谢。
    • @Joe:没关系,但 NInject 与您最初的问题有什么关系?
    • Ninject 自动完成所有这些工作。此外,它使单元测试更加简单。因此,如果这解决了我的问题,并且它是我想开始使用的包,那么我会去做。你的答案也有效。
    • 但是@mm8 的回答仍然是这个问题的答案,所以我认为应该接受它。
    【解决方案2】:

    我们总是使用 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 应该可以按您的意愿工作。每个窗口都会有自己的类实例。

    您需要确保的一件事是自己清理,否则您最终会得到大量的幽灵视图模型。在窗口的 Unloading 事件中,将 DataContext 设置为 null...

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

    【讨论】:

    • 谢谢。我想我现在就开始使用 Ninject,因为这似乎是我前进的方向。
    猜你喜欢
    • 1970-01-01
    • 2013-07-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-14
    • 2011-07-04
    • 1970-01-01
    相关资源
    最近更新 更多