Click here to Skip to main content
14,697,262 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
I am discovering MVVM for the first time and am using Caliburn.Micro.

I can articulate my question with a real example:

In my View I have a combobox from which the user can select an available Comport. The selected item is bound to a property in the ViewModel.
In one of my Models I have a scanner class which will use the Comport that the user selected.

This means that the scanner class needs to know about changes to the Comport property in the ViewModel. The question is, what is the best way to implement this?

I have considered:

1: Set properties / call methods in the Scanner class directly from the ViewModel when there is a change:

public string SelectedPartScannerComPort
{
   get { return _selectedPartScannerComPort; }
   set
   {
       _selectedPartScannerComPort = value;
       NotifyOfPropertyChange(() => SelectedPartScannerComPort);
       OnSelectedPartScannerComPortChanged();  // Access model directly from this method in the ViewModel to make changes.
   }
}


...
...
private void OnSelectedPartScannerComPortChanged()
{
    Models.Equipment.PartScanner.SetupPort(SelectedPartScannerComPort); // Access the model to implement the change.
}


This works but it means that the ViewModel has code in it which is specific to the operation of the Model.

2:
I believe the notifying property in the ViewModel is an event, so I should be able to subscribe to it from the Model.
// In the Model:
shellViewModel.SelectedPartScanner.PropertyChanged += OnPartScannerPropertyChanged;

I haven't been able to try it as I am struggling to discover where the ShellViewModel is declared so that I can access its instance to subscribe to the events.
In any case, this would mean the Model needs to know about the View Model.

It seems like no matter what I will do, either the ViewModel needs to know about the Model or the Model needs to know about the ViewModel.
Is this acceptable practice? Are there better ways to go about this?

What I have tried:

I have tried directly setting properties / calling methods in the model from the viewmodel. It works but I am concerned that I am misunderstanding MVVM.
Posted
Updated 1-Sep-18 2:33am
v3

1 solution

If your base class for your Model implements the INotifyPropertyChanged, then your ViewModel can subscribe/unsubscribe from the Model's PropertyChanged event.
   
Comments
Brian J Hoskins 1-Sep-18 7:40am
   
Thanks for the response Graeme. I believe you have slightly misunderstood my question: I want to inform the Model of a change in the ViewModel, not the other way around.
However, your answer is still useful as I am confused about this exchange of information more generally and that is really the purpose of my question.

So, inevitably the ViewModels and the Models will be linked through code like this and there will not be 100% seperation of concerns. It seems that there cannot be: how else can the Models do useful work in response to changes to the ViewModels?

That said I think I am also misunderstanding the purpose of Models. It is explained in many tutorials that the Models contain your data and this drives the ViewModel to inform the GUI of changes to data.
This makes sense with the direction in which you have answered my question.

But I have a different application to this. I have pieces of equipment which do things, and I can set the equipment up and operate them from the GUI. So it seems to me that the data flow is more from ViewModel -> Model than Model -> ViewModel. But also the data flow can be both ways I think?

I get the general impression that I am misunderstanding something fundamental about MVVM but so far no amount of googling or tutorial reading has helped me make progress.
Graeme_Grant 1-Sep-18 8:10am
   
Okay. To answer your comment I'll explain how I handle this scenario.

1. Models for me are a data container, pretty much a POCO with INotiftPropertyChanged implemented.
2. ViewModels are the interface between the Model and the View. Pretty standard.
3. Any specialized functions are broken between Repositories for handling storing/retrieving data and Services which support specific tasks. Repositories and Services are accessed via the ViewModel.

With the above approach, there is no need for the ViewModel to notify the Model, the ViewModel will interact with/notify the Repository/Service.

Hope this makes sense.
Brian J Hoskins 1-Sep-18 8:45am
   
Yes this makes perfect sense. Thank you Graeme!

I was mainly concerned that I was not using the MVVM framework as it is intended and I didn't want to carry on writing an entire application just for it to be pointed out that I was totally misunderstanding what I was supposed to be doing.

You have given me the confidence to proceed and I consider the question answered, thanks!
Graeme_Grant 1-Sep-18 16:39pm
   
You are most welcome Brian. :)

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900