I have my MVVM and the model consists of a number of related classes, but for the sake of this question we'll focus on just four.
GrandParentModel, ParentModel, ChildModel and Contact.
These all inherit from ModelBase which has an implementation of INotifyPropertyChanged on it.
So each of the three models has a Contact property. If Child doesn't have a property it is supposed to look to Parent, and if Parent is blank it will look to GrandParent. If the contact changes at the grandparent level I'd like any dependants, ie any sub parents and their children to raise a PropertyChanged event for their Contact too.
I think everything I'm going to do will be supported by the DependencyProperty system, but I don't want to use that as this is my 开发者_开发问答Model, separation of concerns and all that. So I'm putting together a mini implementation, which is all fine.
My question is has anyone been down this path before and is there anything I should be worried about in the future? My Spidey-Senses are tingling and I don't know why.
Thanks Ian
Edit: The relationship between the objects here is that a grandparent has any number of parents has any number of children. My current model has a property on each which points at the parent (null in the case of a grandparent) and a parent/grandparent has a collection of child objects.
I've been down this path, and it's not pretty. Basically you have to subscribe to the PropertyChanged
event of ParentModel
from your ChildModel
. You have to take care if your child can change parents. Then when you get notified of a change in the parent from the child's point of view, you have to raise your own PropertyChanged
event on the child. It gets ugly because you can end up with hanging event handlers that you forgot to clean up.
A better method would be to create your own Model-specific analog to DependencyProperty
. Basically in your constructor of ChildModel
you "declare" that property Contact
delegates to property Contact
of object Parent
when null. You do that using a little helper class that observes the PropertyChanged
event on the ParentModel
object and have it execute a PropertyChanged
event on the child when appropriate. Also have it watch for the Parent
property to change on the child.
You could use the MVVM Light message bus. Have the grandparent and parent all send a message when their Contact
property changes. Have the child listen for those messages. When it gets a message, then check to see if it matches its own parent or grandparent, and raise a PropertyChanged
event if necessary. This is better than either method above because you don't have to keep track of when your parent or grandparent changes. You're less likely to have bugs. It also uses weak references, so it won't hold on to objects the way event handlers do.
Now what I've been doing is getting away from having my model objects implement INotifyPropertyChanged
. I introduced a Presenter
layer between my Model and my ViewModel. The Presenter
actually constructs a ViewModel out of small ViewModel "widgets" (one widget might be a ChangeValue<T>
widget, for instance). I have a rules engine that tells the Presenter
how to compose a ViewModel out of widgets for a given Model. The Presenter
handles all user input (basically executing a lambda against the Model), but since it knows that a user action just took place, it knows that something in the Model might have changed. After the Model action is complete, it copies all of the data from the Model to the ViewModel. The ViewModel inspects the incoming data and raises a PropertyChanged
event if the field actually changed. Obviously that's the most compliated way of doing it, but it gives you a really clean Model and neither the ViewModel nor the Presenter contains any Model (domain/business) logic.
精彩评论