Аналог DependencyProperty для модели WPF MVVM - PullRequest
3 голосов
/ 12 января 2011

У меня есть MVVM, и модель состоит из ряда связанных классов, но ради этого вопроса мы сосредоточимся только на четырех.

GrandParentModel, ParentModel, ChildModel и Contact.

Все они наследуются от ModelBase, в котором есть реализация INotifyPropertyChanged.

Таким образом, каждая из трех моделей имеет свойство Contact.Если у Child нет свойства, он должен смотреть на Parent, а если Parent пуст, он будет смотреть на GrandParent.Если контакт изменится на уровне бабушки и дедушки, я бы хотел, чтобы любые иждивенцы, то есть любые родители и их дети, также инициировали событие PropertyChanged для своего контакта.

Я думаю, что все, что я собираюсь сделать, будет поддерживаться системой DependencyProperty, но я не хочу использовать это, поскольку это моя Модель, разделение интересов и все такое.Так что я собираю мини-реализацию, и все в порядке.

Мой вопрос: кто-нибудь был на этом пути раньше и есть ли что-то, о чем мне следует беспокоиться в будущем?Мои чувства-пауки покалывания, и я не знаю, почему.

Спасибо, Ян

Редактировать: Отношения между объектами здесь таковы, что у бабушки и дедушки есть любое количество родителей, есть любое количество детей,Моя текущая модель имеет свойство для каждого, которое указывает на родителя (null в случае дедушки и бабушки), а родитель / дедушка имеет коллекцию дочерних объектов.

1 Ответ

2 голосов
/ 13 января 2011

Я шел по этому пути, и это не красиво. По сути, вы должны подписаться на 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 не содержат никакой логики модели (домен / бизнес).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...