13

Following WPF MvvmFoundation, linking the View with the ViewModel has many choices like described on http://www.paulstovell.com/mvvm-instantiation-approaches.

However their example has nothing about how to link the ViewModel with the Model.

Traditionally I created the model first and then one or more views that render it. It seems that MVVM pushes people to create the View, which creates the ViewModel, which create the Model. I hope it's not the case as wiring a complex business model with various ModelView can else be tough.

How do you instantiate your business model classes in MVVM and link them with your ViewModels?

Wernight
  • 36,122
  • 25
  • 118
  • 131
  • I found some info about this issue on http://marlongrech.wordpress.com/2008/03/20/more-than-just-mvc-for-wpf/. The solution talked is using **mediator design pattern** via for example the *Message* of MVVM Foundation. This help inter-ViewModel communication which is part of the problem. – Wernight May 26 '11 at 11:58

5 Answers5

16

I normally pass Model objects as constructor params to VM. I use App class as the controller which will initialize MainWindow, MainWindowViewModel with the main model. There after the MainWindowViewModel takes care of initializing other VMs with appropriate model objects.

    private void Application_Startup(object sender, StartupEventArgs e)
    {
        mainWindow = new MainWindow();
        mainWindow.DataContext = new MainWindowViewModel(new Model());
        mainWindow.Show();
    }
Souvik Basu
  • 3,069
  • 4
  • 28
  • 42
6

You create your BusinessModel classes inside your ViewModel.

So in your CustomerViewModel you would say this.CurrentCustomer = new CustomerModel(), and your CustomerView would bind to the CurrentCustomer property on the ViewModel

If you are interested, I wrote up a simple sample using MVVM as an example of how the View, Model, and ViewModel interact.

Rachel
  • 130,264
  • 66
  • 304
  • 490
  • That's how I saw it usually works but it's pretty hard when you've a model composed of **multiple interconnected** classes that do something in background. Then various *ModelView* would like to access various classes in the model. Of course the model could be **shaped to support that**, but then it wouldn't really be a business model. – Wernight May 26 '11 at 07:19
  • 1
    @Wernight Models should not be doing anything in the background. They're just dummy containers to hold data. Background processes should be run in a ViewModel. What sort of processes does your model run? – Rachel May 26 '11 at 11:35
  • @Rachel: The example on http://marlongrech.wordpress.com/2008/03/20/more-than-just-mvc-for-wpf/ would suffice. The *Search* and the *ProductList* should display all items, thus looking into the same *ProductList* model. This means the ModelView shouldn't directly create the model. – Wernight May 26 '11 at 13:19
  • @Wernight The link you posted does not use MVVM. It uses MVC, which is not the same. If you want to implement similar communication between your ViewModels in MVVM, I'd recommend you look into MVVM Light's `Messenger` or Prism's `EventAggregator` – Rachel May 26 '11 at 20:19
  • @Rachel: Yes of course. I meant it only as a hint of solution. I used that way for some inter-ViewModel communication. Still for the business logic which should be in the inter-connected models the problem has no simple solution if MVVM it seems. – Wernight May 27 '11 at 07:48
  • @Wernight that sort of business logic should exist in the ViewModels – Rachel May 27 '11 at 11:41
2

I use dependency injection/MEF to do this. Just export all of my model classes all the way down the chain, and have them imported for me automatically into the ViewModel constructor.

Justin Simon
  • 1,133
  • 8
  • 8
2

I take a variety of different approaches depending on the situation. I've found that when it comes to getting this data linked, one size does not fit all.

For simple cases, I will have the ViewModel and the Model be the same thing. Obviously not that good for all cases, but sometimes there is just no need to go the extra mile to split the M from the VM. (Great for cases where you have, say, listbox items that have scant information)

Sometimes, especially when the model is a chunk of code you don't have access to (written by another developer) it is easy to subclass the model, and add all of your VM things (observable properties, etc.) on to it.

Lastly, I will use the approach that is mentioned by Souvik. Construct the VM with the model information that you want to use as a parameter, or allow it to be passed in otherwise. This is probably the most common approach for my larger and more complex Model / ViewModel relationships.

A.R.
  • 15,405
  • 19
  • 77
  • 123
0

I am auto-passing IRepository instance to VM constructor using IoC container and everything VM needs to do with models is done via this repository. Repository is class which: Create, read, update and delete data. When I need to show some view (window), I use IViewService.ShowDialog(viewModel As ViewModelBase). In implementation of IViewService, there are views registered with VMs, so VMs only need to know other VMs and not their views (like "Show me view for this view model").

Ondřej
  • 1,645
  • 1
  • 18
  • 29