0

In my WPF application, my Model class inherits from a class ParentClass as such:

Model : ParentClass, INotifyPropertyChanged

My application is simply meant to provide a UI to test and validate ParentClass. So Model really is not much more than an INotifyPropertyChanged implementation layed over ParentClass

However I still need to access the data from that parent class and have it be responsive to the UI.

Assuming Slicing is a property in ParentClass, and WPFSlicing is a property in Model, this is how I am currently doing it. I am wrapping every parent property in a WPF-compatible property.

public Thickness WPFSlicing
{
    get { return Slicing; }
    set
    {
        Slicing = value;
        OnPropertyChanged("Slicing");
    }
}

Is there a smarter way to do this? I have many properties in my parent class and this seems like a very uninspired method.

  • 1
    Yes, you need to call OnPropertyChanged("propertyName") for every setter :( – Jon Aug 13 '14 at 14:37
  • It seems that you do not have a good separation for View, Model and ViewModel. Perhaps you can edit your question to show which of your classes correspond to which of the MVVM domains. – Mare Infinitus Aug 13 '14 at 14:39
  • Is it not common to implement INotifyPropertyChanged in the model? – William Thomas Waller Aug 13 '14 at 14:40
  • you will need it. But maybe you are looking for this. http://msdn.microsoft.com/en-us/library/ms165394.aspx – Core-One Aug 13 '14 at 14:40
  • I'm unsure how that link is relevant, @Core-One – William Thomas Waller Aug 13 '14 at 14:42
  • 1
    If your version of VS supports Macros (or [Macro Alternatives](http://stackoverflow.com/q/12027485/302677)), I find it fastest to just record a macro that will write out all the property change stuff for me. I have an example [here](http://stackoverflow.com/a/14261661/302677) if you're interested. – Rachel Aug 13 '14 at 15:13
  • If your model has properties of type Thickness and other such UI specific types, then you're not really MVVMing, and so do whatever the hell you want--it doesn't matter. –  Aug 13 '14 at 16:17
  • `ParentClass` is render-able data, for use outside of my application. In the context of my application, it's still just model data. – William Thomas Waller Aug 13 '14 at 17:05

2 Answers2

1

This is a very interesting question.

Typically, I've found that in MVVM applications, you're trying to isolate a model as an end-result -- a product/piece of data -- of the View Model. If you were to have a Bicycle shop, for example, you would see the Storefront as the View, the Sales Person as the ViewModel (assuming this is a customizable Bicycle that is built to order), and the Model as the finished Bicycle object.

In the case of building the Bicycle, while it is in a "prototyping" stage that needs to be represented, I tend to wrap that up in a ViewModel -- because there is logic in it. It seems like an extra step, but in the end, you can have validations at that ViewModel while constructing it. If your model is inflexible to have the INotifyPropertyChanged added to it (or if it was generated from a service), you'll have issues if you have "0" tires on the Bicycle -- that should cause problems!

A lot of folks tend to get a little lazier and see MVVM as a pattern that abstracts out prototyped models (where data input is going back/forth, updated) to models -- when they should in fact be ViewModels.

Per the example, I would have an MVVM Directory that looks like:

Models
  -Bicycle (an object that can be passed across a service, etc -- data)
Views
  -BicycleCreatorView (the view or data template of the model)
  -StoreFrontView (the view of the entire store/app)
ViewModels
  -BicycleCreatorViewModel (the view model which CONSTRUCTS a Bicycle model as the end     result)
  -StoreFrontViewModel (the view model for the entire store)

Now, you could very easily ALSO have the BicycleCreatorViewModel have a constructor which takes in a Bicycle model and pre-populates. That's not uncommon. Someone might come into a store and say, "Hey, can you make this similar to this other one? Here's what it looks like." While the end-result is to have another property (probably just a get {}) which actually renders a Bicycle object, IF validation is good and we don't have something unusual with 0 tires, no seat (maybe that's a feature?), etc.

So, in short -- I would always have your Model (if you cannot extend it in ANY way) be wrapped up into its OWN ViewModel, for this purpose. That would be the true MVVM pattern. You can always use stuff like ReactiveUI or other toolkits that can wrap the properties up. You may spend a little more time doing this, but the end-product will be far more flexible and less error-prone than one otherwise. Essentially you are doing this already, but you could probably rewrite it so it seems "cleaner" and has the line's drawn.

In theory, you might also inspect whether you could approach it in a method like this:

Is there an aspect-oriented toolkit you could use, potentially? Maybe make your classes partial to include INotifyPropertyChanged on the extension and then XmlIgnore certain pieces, if serialization is an issue/at question?

Problem is we have very little knowledge on where the model comes from and how you're using it. Hope that helps or gives you an interesting idea. Would love to see if you come up with a solution that is more "inspired" than the standard.

Locke
  • 1,133
  • 11
  • 32
  • Thanks for the long answer! I actually wasn't even thinking of `Model` as a ViewModel for `ParentClass`, but now that I think about it, that really is what it is. – William Thomas Waller Aug 13 '14 at 15:06
0

I offer an alternate view. This all can be extremly simply solved with AOP framework, such as PostSharp. All you do, is attach [NotifyPropertyChanged] attribute to your class, and your model has everything wired up.

http://www.postsharp.net/aspects/examples/inotifypropertychanged

Be warned though, it costs, but it can be good investment, imo.

Ps, it's matter of view, but I don't see anything wrong with having all the DOMAIN model classes implement INotifyPropertyChanged. It doesn't kill performance, the only downside is that it clutters the code a little. That's what I have done, my domain model entities implement from CommonEntity, and INotifyPropertyChanged. INotifyPropertyChanged is not part of WPF!

It works, and is definitely nicer than wrapping your models inside viewmodels.

Erti-Chris Eelmaa
  • 25,338
  • 6
  • 61
  • 78
  • I'm actually just an intern and `ParentClass` is a class that would make people very angry if I touched haha. Otherwise I would certainly look into `ParentClass` implementing `INotifyPropertyChanged` – William Thomas Waller Aug 13 '14 at 15:10
  • I love this solution for AOP, but if your contract is locked, you cannot just decorate the contract with a tag. I agree AOP provides a lot of cool functionality, but if you're locked in that your model comes from something beyond your control (say a Communication Layer DLL with contracts), the only real choice is to build something. But in lieu of the question, the above answer is an "interesting" way to avoid having to write all of the extra "OnNotifyPropertyChanged" etc, calls. – Locke Aug 14 '14 at 14:11