Я шел по этому пути, и это не красиво. По сути, вы должны подписаться на PropertyChanged
событие ParentModel
от вашего ChildModel
. Вы должны позаботиться о том, чтобы ваш ребенок сменил родителей. Затем, когда вы получите уведомление об изменении родителя с точки зрения ребенка, вы должны инициировать собственное событие PropertyChanged
для ребенка. Это уродливо, потому что вы можете получить обработчики событий, которые вы забыли очистить.
Лучшим способом было бы создать свой собственный специфичный для модели аналог DependencyProperty
. По сути, в вашем конструкторе ChildModel
вы «объявляете», что свойство Contact
делегируется свойству Contact
объекта Parent
, когда оно равно null. Вы делаете это с помощью небольшого вспомогательного класса, который наблюдает за событием PropertyChanged
объекта ParentModel
и заставляет его выполнить событие PropertyChanged
для дочернего объекта, когда это необходимо. Также проследите, чтобы свойство Parent
изменилось на дочернем.
Вы можете использовать шину сообщений MVVM Light. Пусть прародитель и родитель отправят сообщение, когда их свойство Contact
изменится. Пусть ребенок послушает эти сообщения. Когда он получает сообщение, проверьте, соответствует ли оно своему собственному родителю или деду, и, если необходимо, вызовите событие PropertyChanged
. Это лучше, чем любой из вышеперечисленных методов, потому что вам не нужно отслеживать, когда меняется ваш родитель или дедушка. У вас меньше шансов иметь ошибки. Он также использует слабые ссылки, поэтому он не будет удерживать объекты, как это делают обработчики событий.
Теперь то, что я делал, это избавляюсь от реализации моими объектами модели INotifyPropertyChanged
. Я ввел слой Presenter
между моей моделью и моей моделью представления. Presenter
фактически создает ViewModel из маленьких «виджетов» ViewModel (например, один виджет может быть виджетом ChangeValue<T>
). У меня есть механизм правил, который говорит Presenter
, как составить ViewModel из виджетов для данной Модели. Presenter
обрабатывает весь пользовательский ввод (в основном, выполняет лямбду против модели), но, поскольку он знает, что пользовательское действие только что имело место, он знает, что что-то в модели могло измениться. После завершения действия Модель копирует все данные из Модели в ViewModel. ViewModel проверяет входящие данные и вызывает событие PropertyChanged
, если поле действительно изменилось. Очевидно, что это самый сложный способ сделать это, но он дает вам действительно чистую модель, и ни ViewModel, ни Presenter не содержат никакой логики модели (домен / бизнес).