Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
253 views
in Technique[技术] by (71.8m points)

c# - MVVM - PropertyChanged in Model or ViewModel?

I have gone through a few MVVM tutorials and I have seen this done both ways. Most use the ViewModel for PropertyChanged (which is what I have been doing), but I came across one that did this in the Model. Are both methods acceptable? If so, what are the benefits/drawbacks of the different methods?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Microsoft's Patterns and Practices, the inventor of MVVM, and I all disagree with the chosen answer.

Typically, the model implements the facilities that make it easy to bind to the view. This usually means it supports property and collection changed notification through the INotifyPropertyChanged and INotifyCollectionChanged interfaces. Models classes that represent collections of objects typically derive from the ObservableCollection class, which provides an implementation of the INotifyCollectionChanged interface.

-- Microsoft Patterns and Practices: http://msdn.microsoft.com/en-us/library/gg405484%28v=pandp.40%29.aspx#sec4

At this point data binding comes into play. In simple examples, the View is data bound directly to the Model. Parts of the Model are simply displayed in the view by one-way data binding. Other parts of the model can be edited by directly binding controls two-way to the data. For example, a boolean in the Model can be data bound to a CheckBox, or a string field to a TextBox.

-- John Gossman, inventor of MVVM: http://blogs.msdn.com/b/johngossman/archive/2005/10/08/478683.aspx

My own article: http://www.infoq.com/articles/View-Model-Definition


It is an anti-pattern to have a "view-model" that just wraps a model and exposes the same list of properties. The view-model's job is to call external services and expose the individual and collections of models that those services return.

Reasons:

  1. If the model is updated directly, the view-model won't know to fire a property changed event. This causes the UI to go out of sync.
  2. This severely limits your options for sending messages between parent and child view-models.
  3. If the model has its own property changed notification, #1 and 2 aren't a problem. Instead, you have to worry about memory leaks if the wrapper VM goes out of scope but the model doesn't.
  4. If your models are complex, with lots of children objects, then you have to walk the entire tree and create a second object graph that shadows the first one. This can be quite tedious and error prone.
  5. Wrapped collections are particularly difficult to work with. Any time something (UI or backend) inserts or removes an item from a collection, the shadow collection needs to be updated to match. This kind of code is really hard to get right.

That isn't to say you will never need a view-model that wraps a model. If your view-model exposes properties that are significantly different from the model and can't just be papered over with a IValueConverter, then a wrapping view-model makes sense.

Another reason you may need a wrapping view-model is that your data classes don't support data binding for some reason. But even then, it is usually better to just create a normal, bindable model and copy the data from the original data classes.

And of course your view-model is going to have UI specific properties such as which item in a collection is currently selected.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...