I have been downloading a lot of example code to help me gain a better understanding of MVVM within silverlight.
One of the things I have noticed is an inconsistency within the sample code I have downloaded. Some for example implement INotifyPropertyChanged on the viewmodels, where others implement it on the Model.
Which is the preferred way of handling property changes, should it be handled at the model level or the viewmodel level?
Handling (Notifying) property changes in the viewmodel would seem more natural if this is to update the item that's being displayed in the view by databinding.
One of the reasons for having a viewmodel in the first place is that it holds the data from the model in such a way that it's easy for the view to bind to it.
So, if the main reason for your INotifyPropertyChange in is to update the item which is bound in the view, you should update it in the viewmodel.
I typically use DependencyProperty instead of INotifyPropertyChanged, but the idea is the same.
Their purpose is to notify the view controls, they are bound to, that they have changed so the view can update. This implies a weak connection between the view and whatever holds the property or object. In MVVM, the view should never have any link to the model because of separation of concerns.
I will often have physically force this by creating a separate project for each of the view, viewmodel, and model. So, the answer to your question is that the INotifyPropertyChanged should be implemented at the viewmodel level because the view should never touch anything from the model level. Having said this, MVVM is just a coding paradigm to make the programmers job easier, so there could be reasons to implement it differently if it means making your job easier and it doesn't having any negative consequences.
Related
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!
In MVP pattern, a Presenter has an interface of View so the presenter can call iview.DoSomething().. What about in MVVM pattern?
According to John Gossman's UML diagram http://blogs.msdn.com/johngossman/archive/2006/04/13/576163.aspx , ViewModel doesn't have an interface of View. So, seems like the ViewModel and View should be communicated via Binding only. (or use attached property or blend behavior or etc).
What do you guys think?
I agree with John Gossman. The way the ViewModel "talks" to the View is through Bindings only. In fact - the ViewModel shouldn't care about the View at all. It should simply make data available through properties, and it's up to the View to decide what it will dynamically bind to in the ViewModels. If the ViewModel wants to tell the View something this should occur implicit through Bindings.
A similar question was asked an hour ago - here.
The whole purpose of MVVM is to vastly reduce the amount of code in your code-behind class of your WPF form or user control. The idea is that anything that would be handled by the view in classic MVC/MVP can be translated over to the VM by using a combination of data binding and/or commands. In my general usage of MVVM I have managed to completely remove all of the code-behind in my forms/user controls and the VM has no direct knowledge of the view it is controlling. If you have a situation that really cant be handled by data binding or a command then please elaborate on your initial question and I (or one of the many, many more talented MVVM'ers on here) will try to point you in the right direction.
It typically does - through events on INotifyProperty changed, if nothing else.
Can a ViewModel talk to View in MVVM pattern?
Yes, but in a decoupled way. It’s allowed to introduce an interface IView for the communication.
The MVVM pattern is about to move the logic from the View into the ViewModel. This way we are able to unit test this logic.
In my WPF MVVM application my model is a complex tree of Model objects wich constantly changes at runtime. Model instances come and go at runtime, change their position within the tree and of course change their many properties. My View is almost a one-to-one visual representation of that tree. Every Model instance is in 80% of the cases also a node in the tree.
My question is now how I would design the ViewModel around this? My problem is that there are quite a lot of different Model types with each quite a lot of properties. If I understood MVVM corretcly the view should not communicate with the Model directly so this would mean that I would have to create a ViewModel type for each Model type and have to rewrap each property of the Model type in the ViewModel.
Also the ViewModel would need to "bind" to the propertychanges of the Model to pass it along to the view (using wpf datatbinding). I would need some factory that creates and introduces a ViewModel instance for each Model that appears anew and I would habe to dispose each ViewModel instance when the corresponding Model disappears. I end up keeping track of all instances I created. It is unbelievable how much bloat code is generated dues to this double wrapping.
Is this really a good approach? Each entity and each property more ore less exists twice and I have a lot of extra code keeping Model and View in sync. How do you handle this? Is there a more clever way to solve this?
Does anyone have a reference/sample implementation for this that does it better than I do?
I think you may run into trap of paradigm if you follow this path. MVVM is nothing more than a pattern, which simplifies development in WPF world. If it doesn't - don't use it or revise your approach. I wouldn't spend 80% of my time just to check the "Using MVVM" field.
Now back to your question. Correct me if I'm wrong, but it sounds like you are looking at MVVM from opposite direction: you don't need Model to ViewModel one-to-one correspondence. Usually you create ViewModels based on your View first, and only then on a Model.
Generally you look on a screen mockup from graphic designers, and create corresponding ViewModel, which takes all necessary fields from the Model, wraps/modify/format/combine them to make View development as easy as possible.
You said that your View is almost one-to-one visual representation of the Model. In this case it may have sense to create a very simple ViewModel which exposes root object of your model-tree, and let View consume model directly via that property. Then if you need some View customizations or commands processing you can delegate that to ViewModel.
Sorry for very vague answer. Maybe if you ask more specific question we could dispel the confusion :)...
Sorry if this has already been asked, but I just want to make sure that I'm doing this right.
If I have a domian object that has say 10 properties on it. I have a grid on my main form that I want to show the pretty much all the the properties from the model.
I created a viewmodel to wrap the domain object to show in the gridview but then I have to expose all the properties again. I just feel binding straight against the model through the viewmodel feels dirty and defects the purpose a bit.
So for example I don't really like this:
{Binding DomainObject.Property}
where DomainObject is property on my view model.
So my main question is, should I expose all the properties on the model through the view model just to bind it to the grid?
EDIT: Just for added information the domian objects are LINQ-To-SQL objects, so I don't think they implement INotifyPropertyChanged but I'm not sure.
Some people will say it doesn't matter, others say it does. I'm in the latter camp, for these reasons:
You increase the dependencies of the view, as it now depends on the data model, not just the view model.
You require the designers need to know the properties and structure of your data model.
You create more work for the (almost inevitable) refactoring when you decide you need a layer of indirection for formatting, validation, or whatever it might be.
As Thomas pointed out, data models often don't implement change notification
Yes, it's a little more work, but I believe it's worth it to reduce decoupling, maintenance headaches, collaboration with designers, and correctness.
PS. If you find yourself in this situation a lot, you might consider an implementation of ICustomTypeDescriptor that wraps any data object and exposes its properties with change notification. That way your VM can extend this generic wrapper until you decide you need to pull properties out for purposes such as formatting and validation.
If you need change notification on the properties and the model doesn't implement INotifyPropertyChanged, then you need to create new properties on the ViewModel. Otherwise, it's probably not a big issue to bind directly to the model : the MVVM pattern is just a guideline, you can bend the rules a little if necessary...
I think it is a matter of personal preference. I happen to believe it is perfectly fine to expose the Model in a single object from the ViewModel. Recreating all the properties of the Model in the ViewModel just results in a bunch of extra code.
However, this only works provided your Model implements change notifications so the data binding works.
Problem Statement
I'm writing a very basic WPF application to alter the contents of a configuration file. The data format is an XML file with a schema. I want to use it as a learning project for MVVM, so I have duly divided the code into
Model: C# classes auto-generated from xsd.exe
View-Model: View-friendly representation of the Model.
View: Xaml and empty code behind
I understand how the View-Model can make View-binding a breeze. However, doesn't that leave the View-Model <-> Model semantics very awkward? Xsd.exe generates C# classes with arrays for multiple XML elements. However, at the V-VM level you need Observable Collections.
Questions:
Does this really mean I have to keep two completely different collection types representing the same data in coherence?
What are the best practices for maintaining coherence between the Model and the View-Model?
I'm not a big expert, but I think that is the case yes. The general idea is indeed to propagate change between the view and the viewModel via Binding, and then between the ViewModel and the Model via events (in the Model -> ViewModel direction) or dependency (in the other direction).
I don't know how standard that is, but my understanding of MVVM is that the ViewModel should hold a reference to the model so that when the user modifies the view, the ViewModel should call the appropriate code on the model. The other way round, the Model should raise events when modified, and the ViewModel should update itself accordingly (the ViewModel being an observer to the model).
#Does this really mean I have to keep two completely different collection types representing the same data in coherence?
I think yes. It's pretty boring, but it works quite well. Hopefully, in the future we will have also a code generator to create the ViewModel part.
Karl is working on that: http://karlshifflett.wordpress.com/mvvm/
You need clearly ObservableCollections at the viewmodel so, yes, you will need two
completely different collection types in the model and in the viewmodel.
I have done an article about doing undo / redo in MVVM where you can find a possible solution to this. It uses what I call the MirrorCollection: an ObservableCollection derived class witch automatically obtains his items from a List (the list of the model).
I think it is an interesting solution, you can find the articles here
Part 1: Using the Viewmodel pattern to provide Undo / Redo in WPF
Part 2: Viewmodelling lists (here is the MirrorCollection definition)
Expose Events or delegates in Model and hook to the same in ViewModel, when ever values in the model changes notify to viewmodel via event or delegates and from Viewmodle you can update the UI.
If you want to update it from view model to model as simple as that just call some method pass the new values