I am building an application that is based on MVVM-Light. I am in the need of creating multiple instances of the same View, and each one should bind to its own ViewModel.
The default ViewModelLocator
implements ViewModels as singletons, therefore different instances of the same View will bind to the same ViewModel.
I could create the ViewModel in the VMLocator as a non-static object (as simple as returning new VM()...), but that would only partially help me. In fact, I still need to keep track of the opened windows. Nevertheless, each window might open several other windows (of a different kind, though). In this situation I might need to execute some operation on the parent View and all its children. For example before closing the View P, I might want to close all its children (view C1, view C2, etc.).
Hence, is there any simple and easy way to achieve this? Or is there any best practice you would advice me to follow?
Thanks in advance for your precious help.
Cheers,
Gianluca.
ViewModel is nothing but a single class that may have multiple models. It contains multiple models as a property. It should not contain any method. In the above example, we have the required View model with two properties.
While a view should only have one viewmodel, a single viewmodel might be used by multiple views (imagine a wizard, for example, that has three views but all bind to the same viewmodel that drives the process).
To answer the question, Yes, each view should have its own View Model. But there is no need to model the entire hierarchy. Only what the view needs.
We will how we can communicate between 2 View Models using Messenger. Then, we will create 2 MVVM Controls by name ControlA, ControlB and try to call a method in which is there is one view model within another view model. Go to Nuget manager and install MVVM Light. Create a Folder structure like below.
There is no obligation to store the ViewModels as singletons in the ViewModelLocator, but it certainly makes them easier to find if the view is a singleton too. Obviously, if you have multiple instances of the same View class, you will have multiple instances of the same ViewModel class, and it cannot be a singleton anymore.
To keep track of the multiple instances of the ViewModel, you can implement a dictionary in the ViewModelLocator that looks up for a ViewModel according to a key. The key can be a unique ID for the view, for example. Once you get hold of the view, retrieve its key and then retrieve the viewmodel from the locator.
Update: Often you don't even need to track multiple viewmodels. For instance, you can have the Messenger class send a message to all instances of a given viewmodel class using the Send overload. So before implementing a dictionary to keep track of the VMs, ask yourself if you really need it! ;)
Hope that helps, Laurent
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With