aryeh
aryeh

Reputation: 1040

How to tell MVVMLight create a new view model?

I am using MvvmLight in a WPF project, and have set up my view model locator as shown in their examples...

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>();
}

I have the following line in the opening tag of my XAML...

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

This works, but the locator always returns the same view model, ie the same instance, meaning that if I have more than one product details window open, they will all share the same view model.

How do I tell MvvmLight to create a new view model when I request one?

Upvotes: 3

Views: 848

Answers (2)

mm8
mm8

Reputation: 169420

How do I tell MvvmLight to create a new view model when I request one?

Use the overload of the GetInstance method that acceps a string and pass a unique string value to it:

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

Upvotes: 4

Avrohom Yisroel
Avrohom Yisroel

Reputation: 9492

We always use Ninject, which seems to do what you want by default:-

First, add a reference to the Nuget package for Ninject

Then add a ViewModelLocator class to your project and use code like the following...

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>();
}

Add a static resource for the locator in App.xaml as follows...

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

Make sure your view models inherit from ViewModelBase...

public class ProductDetailsWindowViewModel : ViewModelBase
  // ...

Then your DataContext should work as you want. Each window will get its own instance of the class.

One thing you need to make sure here is to clean up after yourself, otherwise you end up with loads of ghost view models hanging around. In your window's Unloading event, set the DataContext to null...

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

Upvotes: 1

Related Questions