Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF MVVM: INPC and mediating communication between view model & model

I've read various approaches to communicating changes in model data to the view model. Some suggest that the model should implement INotifyPropertyChanged where possible, so that it may notify the view model of changed properties. Some suggest a service layer between model and view model, with the service layer implementing INPC, method calls being routed through this service layer to the model so that the service layer notifies the view model.

I consider the latter to be a more granular revision of the former and have begun implementing INPC in my model classes. It feels wrong because

a) I now have to write an event handler in my view model for notifications from the model. This takes the form of a long switch(propertyName) which sets the corresponding property(s) on the view model causing NPC to be sent upwards again. I feel like I'm writing a lot of boiler plate code here.

b) View model is now coupled to my model via a bunch of strings that are regulated solely by convention i.e no 'interface' defined. Not to mention the difficulty this causes IDEs.

c) My model has to be modified to accomodate this context! What if it was closed for some reason? I thought patterns like this were designed to increase code reusability & seperation of concerns. Not only this but the code required to fire the INPC events is tedious and repetetive and not really abstractable.

I'm really keen to know how WPF pros approach this problem whether by dependency properties etc. I get the feeling I am missing something. I'm not keen on using a framework as would like to learn 'from the ground up'. I've been away from WPF for a year or two and working with AngularJS recently has made me question my methods here.

Thanks!

like image 803
Drew R Avatar asked Aug 28 '13 15:08

Drew R


1 Answers

For the purpose of this answer, I will call the business object classes 'data types'.

In my personal experience, view models are always tied to the data types. You have to have properties of the types that you want to display, so there will always be a reference from the view models namespace to the data types namespace.

What you call a model (from your description in your comment) sounds like my view models. My view models have properties, mostly of the type of the various data type classes, and methods, whereas my data type classes just hold properties for the most part... they're just holders of data and reporters of changes really.

You seem to be under the impression that the INotifyPropertyChanged interface performs some duties between the 'model' as you call it and the view model classes... in my opinion, that is optional at best... from the INotifyPropertyChanged Interface page at MSDN:

The INotifyPropertyChanged interface is used to notify clients, typically binding clients, that a property value has changed.

Therefore, I see the INotifyPropertyChanged interface as being the 'life-blood' that goes between the views and the view models and data objects. Some developers prefer to 'wrap' each data type in its own view model, but I prefer to implement the INotifyPropertyChanged interface in my data types directly.

The main reason that I do this is so that I can hook into this framework in custom collection classes that I have. This enables me to have collections that are aware of any changes made to any property in any item in the collection among other things. It also enables me to build data synchronisation into my base classes, so that objects know when they have any changes.

It also saves time in creating matching view model classes for each data type class. Why have two classes to do what one can do? I've never needed that level of separation. If I understand you correctly, implementing this interface in your data type classes would negate the need to perform your point a).

Some of your points b) and c) may also be rendered invalid if you can use .NET 4.5 as there is a new CallerMemberNameAttribute attribute that you can use to automatically feed the name of each property to the PropertyChanged handler. I found a good article called C# 5–Making INotifyPropertyChanged Easier with a good description about it.

I've written several large scale WPF applications now and a few frameworks and I've never had a problem with implementing the INotifyPropertyChanged interface in my data type classes. In fact, I don't think that I could have written them in the same time if I had to implement wrapper view model classes for each data type class. This method has served me well so far and I'm planning on sticking with it, until I find a better way at least. However this is all just one developer's opinion and you have to go with what feels right for you.

like image 141
Sheridan Avatar answered Oct 13 '22 08:10

Sheridan