Reputation: 8461
From my reading, one of the advantages about the MVVM is that it offers separation. This is great but there are times when your View may need to know about the surroundings, for example, when dealing with states.
In my project, one of my views activates some background tasks and the results are displayed on screen in real time. The problem is, if I were to then click on my File -> New, I would be able to change the view. This is not desirable whilst the background task is running.
Now, I can think of a way around this, but it seems to be going against the MVVM approach (which for this project, I'd like to use even when it doesn't make sense too (to give me a better understanding of the patterns strengths/weaknesses)).
So, assuming my Project is built using the MainWindow (which has the contextual menu and the ContentControl which displays my View) and a single view. The only way I can see to make this work is to pass an instance of my MainWindow to my View's ViewModel (or maybe by using delegates would also work). I can then control the visibility state of the menus etc... This seems a poor design choice as I'll have to do this for every view I make (more work) and my system is now pretty tightly coupled.
I think this must be a popular problem but I cannot find anything to suggest an approach.
In my head, having an extra file called StateControllingClass or similar would be a good answer, but again, do I still have to pass it as a parameter to all my ViewModels when instantiating them for them to share the same object?
Any way, my question is; Is there a better approach using the standard MVVM approach (meaning, not using a MVVM framework)?
Upvotes: 1
Views: 73
Reputation: 27104
The smaller parts should not know about the whole. So the ViewModel should not know about the main Windows that started it.
And the background task should not know about the ViewModel that started it. It should probably have a cancel method that gets called by the ViewModel that started it.
The ViewModel can then use this method to cancel any tasks it has running when it receives some sort of cancel command
And the main menu's ViewModel can send this cancel command to the active ViewModel when the file/new command gets fired by the menu
Upvotes: 1
Reputation: 417
I think you should look at Event Aggregator pattern. The main idea is that all view models registered in event aggregator. If something happens, you can publish an event to aggregator. Aggregator deliver the event to all interested view models. So you can easily maintain solid state of your application.
You can read more in Jeremy Miller blogpost, and have a look how this implemented in Caliburn.Micro framework.
Upvotes: 2