Let's say I have a simple View that displays a bit of text. The text comes from the View's ViewModel via a string property that is data bound. I would like to be able to set the ViewModel's string by multiple locations in the application.
What is the best practise for getting the instance of the ViewModel at the various points in my application?
I could make the ViewModel singleton but this didn't feel right.
Any suggestions?
I think there are different concepts for that.
Each has it's pros and cons....
1.) If you have have not parameters in the constructor of the view model you could use the DataContext Property of the Control, View, Page to bind the view model. It spin's up a instance per View...
2.) If you have complex or composed view models with constructor injections ... The best way would be the ViewModel Locator Pattern based on a Service Locator Pattern.
http://johnpapa.net/simple-viewmodel-locator-for-mvvm-the-patients-have-left-the-asylum
http://blog.roboblob.com/tag/viewmodellocator/
3.) you have to think about view first or view model first and maybe about something like a view model marriage...
http://wildermuth.com/2009/5/22/Which_came_first_the_View_or_the_Model
HTH
i think you looking for something like a Messenger where your viewmodel can register for messages to change your string property and other components can send a message via messenger.
another approach is the PRISM event aggregator where you can subscribe to events when your string property should be changed.
EDIT: an other but bad way would be to give an instance of your viewmodel to all other locations. but then you have no more loose coupling.
Related
I've just started learning WPF MVVM using Prism and Unity.
Decoupling the view from the viewmodel works pretty well, but I don't get how wire up my viewmodel and my model.
I doesn't feel right to just create a new EntityObject right in my viewmodel. I have already skim-read the WAF BookLibrary sample but it is quite bulky and adds a lot of extra stuff around the essential part (binding between view and viewmodel), and the Prism docs don't say a word (as far as I read it) about viewmodel - model interaction.
Does anyone know a good source that explains how to use viewmodel and model in a clean way or can me give some advise?
Best Regards
Jay
Everyone will have their own opinions on this. Personally I don't mind using the model directly in the view model. For me, the whole idea of a view model is to extend your model in such a way that it can be consumed by a view.
A simple example of this would be person object, It would have model properties like like name and age for instance. When I get to the view model stage I may add properties to it like visibility which would not make sense on the model proper.
Another point to note is I would consider a model to be the data and the view model to be the context. So you may have a "Card" View Model for a person but you may also have a "List Item" view model that represents the same model in a different context, with different view model specific properties.
I do tend to make my models up using interfaces where relevant and use Inversion of control to inject them into the view model, that way the only thing my view model actually knows is that it needs an IPerson and that it will be provided in the constructor.
As I said other people will have different ideas, all are correct and its up to you to work out which one suits your needs.
I'm trying to get to grips with different patterns (MVP, MVVM etc) and find one that suits my needs. After all my reading I'm still not sure. Hopefully someone can shed some light on this for me.
At the moment I have a WPF View which implements an interface ICustomView. This interface is injected into my Presenter. The presenter then is responsible for subscribing to data, managing subscriptions etc. When the data is returned to the Presenter it calls various methods against the Model (an IObservable collection of CustomBusinessObjects). It does this using the interface ICustomView since the IObservable is a property of the Model.
The problem I see with this is the Model is too coupled with the View. Also the Presenter is deciding which methods to call against the Model. At the moment the View consists of a WinForms grid and this is exposed by the ICustomView allowing the Presenter to call methods against the View. However it adds to the coupling of Presenter and View which makes it difficult to swap out this WinForms grid for a WPF grid or chart etc
I am considering making the Model an entirely seperate entity lets say IModel with a single method ProcessUpdate(string topic, IMessage payload). This would move logic away from the presenter into the Model. It would also mean more than one view could share the same model. The custom model could have additional interfaces for specific customisations but the Presenter would only need to know about IModel.
Does this sound like a reasonable idea? Am I missing something here?
Any advice appreciated.
Thanks
I would recommend switching from MVP to MVVM because you are using WPF. I would only use MVP if you were using ASP.Net or WinForms.
That being said, your MVVM objects would be:
Model: Simple data object. It should not contain any functionality such as Save or Edit, but can have Validation logic.
View: Your UI. I usually do mine as a DataTemplate for the ViewModel class type. It should bind to your ViewModel's Properties and Commands.
ViewModel: The piece that combines the two. Any data displayed in the View should bind to a property in the ViewModel. Any commands in your View such as Button Clicks should also point to methods in the ViewModel.
For example, when a user hits a GetCustomer button on the View, the ViewModel should receive the command, go and get the CustomerModel, and expose it's Properties for the View to bind to. When the user hits Save the ViewModel should validate that the Model is valid, and then execute the Save code using its CustomerModel property.
Personally, when using WPF I prefer to use a WPF datagrid, and bind it to a datacontext in the MVVM pattern. I think the first thing you need to get rid of is the WinForms grid (it will be almost impossible to decouple your model/view as long as you are using a WinForms grid.
I would do research on a few different things.
The MVVM pattern
WPF DataGrid
Binding the DataGrid to a DataContext
Once you get to that point, all you will need to do is update your datacontext, and your view will update with it.
Let's say I have a model which exposes a collection of objects which I will display and change in a GUI.
So we have Model exposing a collection of ModelItem.
The View binds to a ViewModel which exposes an ObservableCollection of ViewModelItem. ViewModelItem is the Viewmodel of ModelItem
The View contains a ListBox and a DataTemplate. the DataTemplate is for items of type ViewModelItem. The View DataContext points at an instance of ViewModel. The ListBox binds to the ObservableCollection.
I control all the code.
So far so simple. Question:
Is it acceptable to expose the collection on the Model as an ObservableCollection? Further, is it acceptable to implement INotifyPropertyChanged on Model and ModelItem?
My concern is I'm muddying the separation between model and viewmodel, but then common sense says, here's a mechanism for notifying changes to elements in my model, lets use it...
Just wanted to get some perspective from others.
Thanks
Short answer:
YES. Use your notification interfaces on your model when you need to notify of changes. Do not worry about muddying your code with this. Be pragmatic.
Long answer:
My philosophy goes like this: When implementing MVVM, bind directly to model objects when there is nothing extra to do. When you need something new (new behavior, properties the view will utilize, etc) then you wrap the model objects in ViewModel objects. A ViewModel that does nothing but delegate data from the model is nothing but extra code. The moment you need to do something to that data past what the model object gives you, you introduce the layer.
So, to extend my thoughts further on that, (and to answer your question more directly), there needs to be a way for the model to tell the ViewModel when something changes. Often, model data is immutable so it doesn't need this notification mechanism, so it isn't necessary. BUT, it is also often the case that the model DOES change. When that happens, the model has two options: use a custom notification method (events, delegates, etc) or use INotifyPropertyChanged.
If you look at the namespace for INotifyPropertyChanged, it is in System.ComponentModel -- not the view -- so I prefer to use it in the model. It is a well-known interface and you can use it to bind directly to your model from your view. No need to implement anything different.
Taking this philosophy one step further, ObservableCollection is in System.Collections.ObjectModel -- also not view-specific -- and it implements System.Collections.Specialized.INotifyCollectionChanged which also is not view-specific. In other words, ObservableCollection was designed to be a collection that notifies its observers of changes. If you have a model that needs to do that, then ObservableCollection is your tool. It just happens to be convenient (not by accident, though) that WPF and Silverlight use these interfaces for data binding.
I guess this is a long-winded way of saying: "YES. Use your notification interfaces on your model when you need to notify of changes. Do not worry about muddying your code with this. Be pragmatic."
It is definitely acceptable to do both. I would even say it's required to do both. Your common sense abilities work just fine. :)
I would only add that if you don't need all the MVVM functionality for your ModelItems, then you can cut some corners by exposing an ObservableCollection<ModelItem> instead of an ObservableCollection<ViewModelItem>, and modifying your DataTemplate to suit. This will save you quite a bit of "preparation" code, so weigh the pros and cons.
It's certainly acceptable to use change notification in the data model if the data model needs change notification. It's also questionable to use change notification in the data model just because the UI needs change notification.
Generally, I design the data model as if there were no UI, and use the view model as an abstraction layer that hides the data model's implementation details from the UI. On the other hand, in a dynamic application it can be the case that the need for change notification is pervasive enough that it just makes more sense to put it in the data model.
No. It's horrible. Your model should not know how it is used. Giving it this knowledge defeats the object of MVVM.
The model should never know it is being used by WPF, winforms, a dos console, as a service or as a lib. If you tell it this, you are going wrong.
It should also be framework independent, not minding if it's part of MVVM, MVC or MXXX!
I am new to MVVM, and I am trying to implement a simple application, following the pattern.
For simplicity, I am breaking the problem down to it's simplest form. If I manage to get this to work, I will have little trouble getting the application made.
The simple application consists of a tabcontrol. It is important that both tabs have their own ViewModel. However, they will get most of their data from the same source. The main issue is to get the second tab to know that the first have initiated a change on the datasource.
So, for simplicity, let's just say that the model is holding a single integer. This integer needs initially to be set to 1.
The first tab is holding a textblock and a button. The text of the textblock is bound to the integer in the datamodel. Upon pressing the button, the integer in the moddel should be incremented with 1.
The second tab holds only a textblock, also bound to the integer in the datamodel. The challenge is to get this textblock to update along with the first textblock, but still being it's own viewmodel.
I need somewhere central to store the values of the model, and in some way, let the viewmodels know that they have been updated, so their properties can be updated, and the Views therefore get's updated accordingly.
Can someone explain in as much detail as possible how this is done? I have tried a billion different ways, but I am not getting it to work.
Let me see if I have your question down right:
You have a data source (your model).
You have 2 view models.
View model 1 changes data in the model.
View model 2 needs to update with changes in the model.
If that all sounds right, here's one solution:
Have your model implement INotifyPropertyChanged. When the integer changes, raise the PropertyChanged event. In view model 2, listen for the model's PropertyChanged event. When it occurs, raise view model 2's property changed event, and its UI will get updated automatically.
I have no idea in which scenario you want to do that.
But a solution that crosses my mind is to have a "parent" ViewModel that holds instances of the two tab ViewModels.
e.g.
public class ParentViewModel{
private Tab1ViewModel viewModel1;
private Tab2ViewModel viewModel2;
}
Then the ParentViewModel can subscribe to the INotifyPropertyChanged event of the ViewModel1 and set the value on the ViewModel2.
I have recently implemented something similar to this. It was for implementing a wizard, consisting of:
7 Views
8 View models
1 Model
The main ViewModel created the Model and passed this on to all the other view models through their constructors.
In your scenario you could have a main ViewModel with an ObservableCollection of ViewModels. Each of these VM's would have the same instance of the model as their data source.
As previously mentioned, implement INotifyPropertyChanged on the model and bind the views directly to the model through a property on the ViewModel. I found this diagram very useful : http://karlshifflett.files.wordpress.com/2009/01/wpflobmvvm1.png
As I wrap my head around the mvvm thing, the view is the view, and the viewmodel is 'a modal of a view' and the model are the entities we are dealing with (or at least that is my understanding). But I'm unclear as to what and when the model entities are populated. So for example:
Lets say I have app that needs to create a new record in a DB. And that record should have default values to start with. Who is responsible for the new record, and getting the default values. Does this have anything to do with MVVM or is that part of a data access layer? Who calls the the viewmodel?
Or for existing records when\where are the records retrieved? And saved if altered?
Thanks
In an overly simplified answer, your ViewModel should contain the LOGIC for controlling what your View displays, as well as how it is allowed to interact with the Model or Data.
Events like Getting data, Saving and Deleting are intercepted through a Command mechanism and pushed into the ViewModel, where they can be tested. Handling 'Dirty' events are also the duty of the ViewModel. As for who Calls the ViewModel, you are entrusting the Calling to the Binding mechanisms available within WPF and Silverlight.
Within the ViewModel it is still about staying with best practices and ensuring that you have a DataAccess layer abstracting your Data Source and possibly using the Repository pattern to abstract that.
The life cycle of a ViewModel could be as simple as the following...
Constructor called by View
GetData method called by ViewModel Ctor
Data received and pushed into existing View databound ObservableCollection property
However since you will probably have a lot of moving parts within the Ctor of the VM, including the Data Repositories Interface you will probably want to work with an IoC. This will make the life cycle of the ViewModel closer to...
View/ViewModel (Depends if you are View or ViewModel first) is pulled out of the IoC
IoC Handles the pairing of the View-ViewModel (Convention based)
Data Repository is Injected into the ViewModel
GetData method called by ViewModel Ctor
Data received and pushed into existing View databound ObservableCollection property
This may seem like more steps, however with an IoC container you are really just calling a single method like IoC.Get(), and the rest of the steps are wired up automatically based on the conventions applied.
I use view-models to control loading (with defaults) and saving my models, and to create collections and objects that I use to bind to my views. This includes setting default values on my models.
State and Bahavior of your view is define in your viewmodel which means all events are declared here.
Who calls the the viewmodel?
it depends who needs it. you can call it in your view.
for existing records when\where are the records retrieved? And saved if altered?
saving and retrieving part is in your viewmodel.
For detailed explanation, visit this site.