In an MVVM implementation, is every ViewModel
coupled to just one Model
?
I am trying to implement the MVVM pattern in a project but I found that sometimes, a View
may need information from multiple Models
.
For example, for a UserProfileView
, its UserProfileViewModel
may need information from UserAccountModel
, UserProfileSettingsModel
, UserPostsDataModel
, etc.
However, in most articles I read about MVVM, the ViewModel only consists on one Model via Dependency Injection. So the constructor takes in only one Model.
How would the ViewModel
work when it has to get information from multiple Models
? Or would such a situation ever occur in MVVM?
PS: I am not using the Prism or Unity Framework. I am trying to implement similar patterns into a project that I am working on which doesn't use Prism or Unity. That's why I need to understand exactly how some of these things work.
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.
One way to have disconnected ViewModels communicate to each other is to use a publish / subscribe mechanism such as PRISMs EventAggregator. However, in a parent / child ViewModel relationship, I think it's fine for the parent to have direct knowledge and control over the child ViewModel.
Yup, each view should have its on ViewModel. I don't know WPF inside out, but generally the ViewModel mediates between a UI component and a business logic component. In other words: It's specific to a view/model pair - this is the only reason for this component to exist...
Having a master ViewModel with several child ViewModels is very handy if you have a complex UI. The main ViewModel may be responsible for handling the top level UI controls and for coordination of the child VMs, while other ViewModels are responsible for communication with the sub regions of your UI.
In my understanding of the MVVM pattern, the only practical requirement is that the View gets all its data from the properties of a ViewModel (probably through a binding mechanism). The ViewModel is a class that you craft specifically for that view, and takes on the responsability of populating itself as required. You could think of it like ActiveRecord for the view.
As such, it doesn't matter what you do inside the ViewModel to obtain the data that its properties should show. You could get it by querying some services, reading one or more business entity models, generating it on the spot, or all of the above. It's perfectly normal to need a combination of all these things to make a functional view.
As in any presentation pattern, the point is just to separate the process of showing some data on the screen, from the process of obtaining that data. That way you can test each part of the process separately.
Edit: Here's a small but hopefully complete example of the flow of dependencies.
// Model/service layer public class MyModelA { public string GetSomeData() { return "Some Data"; } } public class MyModelB { public string GetOtherData() { return "Other Data"; } } // Presentation layer public class MyViewModel { readonly MyModelA modelA; readonly MyModelB modelB; public MyViewModel(MyModelA modelA, MyModelB modelB) { this.modelA = modelA; this.modelB = modelB; } public string TextBox1Value { get; set; } public string TextBox2Value { get; set; } public void Load() { // These need not necessarily be populated this way. // You could load an entity and have your properties read data directly from it. this.TextBox1Value = modelA.GetSomeData(); this.TextBox2Value = modelB.GetOtherData(); // raise INotifyPropertyChanged events here } } public class MyView { readonly MyViewModel vm; public MyView(MyViewModel vm) { this.vm = vm; // bind to vm here } } // Application layer public class Program { public void Run() { var mA = new MyModelA(); var mB = new MyModelB(); var vm = new MyViewModel(mA, mB); var view = new MyView(vm); vm.Load(); // show view here } }
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