0

I'm new to MVVM in a WPF project. As to my understanding, the View is the objects created by xaml files (window, grid, usercontrol). The Model is my data. The View-Model is some other object instance.

I have defined all the VM classes, but my questions is where is the best place to instantiate the VM instance? to be more specific, where should I declare the VM member variable and call the new() function?

Currently I defined a static member variable of the VM and declare it inside my usercontrol. The VM should be accessed by several Views and that's why I declared it as static.

It's kind of ugly, I think, from the Object Oriented design, because I'm using static or global variables.

So what's the common place to declare VM instances?

Felix
  • 2,673
  • 3
  • 30
  • 38

2 Answers2

1

A good way to solve this problem is to create and share your viewmodels in a "Viewmodel-Locator" class like in the code templates of the MVVM-Light Framework. MVVM Light comes with a small IOC container that manages instantiation of your viewmodels and services. Here is some example code: First register your services and viewmodels in a static way:

public class ViewModelLocator
{
    static ViewModelLocator()
    {
        ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
        //Resgister your Services
        SimpleIoc.Default.Register<IDataService, SomeDataService>();

        // Register your Viewmodels
        SimpleIoc.Default.Register<SomeViewModel>();
    }

Create a property for each of your registered Viewmodels to access them from outside the viewmodelLocator class:

 public SomeViewModel SomeVM
 {
     get
     {
         return ServiceLocator.Current.GetInstance<SomeViewModel>();
     }
 }

Next, create a globel resource for example in App.xaml to access your ViewmodelLocator class in XAML.

 <Application.Resources>        
        <vm:ViewModelLocator x:Key="Locator" d:IsDataSource="True" /> 
</Application.Resources>

Bind your datacontext in your view like this:

 DataContext="{Binding SomeVM, Source={StaticResource Locator}}"

Finally in your viewmodel class you can access your services and do whatever you need to do:

class SomeViewModel
{
    private IDataService mDataService;

    public SomeViewModel(IDataService _dataService)
    {
        mDataService = _dataService;

        // Do the fancy stuff...
    }
}

Hope this is helpful!

Tobias Hoefer
  • 1,058
  • 12
  • 29
0

I personally use a 'KEEP IT SIMPLE STUPID" approach. I have a Models folder called NameSpace Models and a ViewModel folder NameSpace ViewModels.

The Models folder holds straight data that replicates the data I get from my WCF service. This could also work for an EDM.

The ViewModels folder holds the actual data I need for a certain Window or Page i.e. I may need a list of Years and a particular Client so my ViewModel will call the YearList model in the 'Models' folder and the Client model from the 'Models' folder.

i.e.

ViewModel

class ClientDetailsViewModel
{
    public ClientModel ClientModel { get; set; }
    public YearListModel YearList { get; set; }

    public ClientDetailsViewModel(ClientModel _ClientModel)
    {
        ClientModel = _ClientModel;
        YearGroupList = new YearGroupListModel();
    }
}

I would then bind the ViewModel to the Window or Form and bind the data using for example:

{Binding ClientModel.ID}
{Binding YearGroupList.Years.ID}