В модели MVVM модель должна реализовывать интерфейс INotifyPropertyChanged? - PullRequest
56 голосов
/ 03 августа 2011

У меня есть четкое представление о View и ViewModel в шаблоне MVVM.Я планирую реализовать шаблон MVVM в моем приложении.У меня проблема с моделью.У меня есть файл .xml, который анализируется, и информация отображается в представлении.

Мне нужно получать уведомления об изменениях в модели только в первый раз.Отныне по требованию я должен быть уведомлен.

Так как реализовать модель?

Должен ли я также реализовать интерфейс INotifyPropertyChanged в классе модели?(Я читал, что модель не должна реализовывать интерфейс INotifyPropertyChanged, так как он специфичен для WPF)

Ответы [ 6 ]

46 голосов
/ 03 августа 2011

Реализация INotifyPropertyChanged в моделях полностью приемлема -

Как правило, модель реализует средства, облегчающие привязать к виду. Обычно это означает, что он поддерживает свойство и коллекция изменила уведомление через INotifyPropertyChanged и INotifyCollectionChanged интерфейсы. Модели классов, которые представляют коллекции объектов, как правило, происходят от ObservableCollection<T> класс, который обеспечивает реализацию INotifyCollectionChanged интерфейс.

Хотя вам решать, хотите ли вы этот тип реализации или нет, но помните -

Что если в ваших модельных классах не реализованы необходимые интерфейсы?

Иногда вам придется работать с объектами модели, которые не реализовать INotifyPropertyChanged, INotifyCollectionChanged, IDataErrorInfo или INotifyDataErrorInfo интерфейсы. В этих случаях модель представления, возможно, должна обернуть объекты модели и выставить необходимые свойства для просмотра. Значения этих свойств будут предоставляться непосредственно объектами модели. Модель представления будет реализовать необходимые интерфейсы для свойств, которые он выставляет так что представление может легко привязать к ним данные.

Взято из - http://msdn.microsoft.com/en-us/library/gg405484(PandP.40).aspx

Я работал в некоторых проектах, где мы не реализовали INotifyPropertyChanged в наших моделях, и из-за этого мы столкнулись с множеством проблем; В VM требовалось ненужное дублирование свойств, и в то же время нам приходилось обновлять базовый объект (с обновленными значениями), прежде чем передавать их в BL / DL.

Вы столкнетесь с проблемами, особенно если вам нужно работать с коллекцией объектов вашей модели (например, в редактируемой сетке или списке) или со сложными моделями; объекты модели не будут обновляться автоматически, и вам придется управлять всем этим в вашей виртуальной машине.

15 голосов
/ 03 августа 2011

Стандартный подход MVVM заключается в реализации INotifyPropertyChanged только в ViewModel. Цель состоит в том, чтобы обновить соответствующие привязки в представлении, когда что-то изменяется в модели представления.

Однако эта цель изменяется на ViewModel с помощью View . То есть, когда вы изменяете значение в TextBox, реализация INotifyPropertyChanged в ViewModel обновит связанные привязки, поэтому представление обновляется корректно.

Он не охватывает изменения, сделанные в модели из внешнего источника, такие как изменения базы данных или другой интерфейс. Пока все модификации данных происходят из View, ViewModel должен знать обо всех изменениях и знать, что обновлять. Например, если вы знаете, что изменение переменной Foo в вашей модели также изменит значение Bar в вашей модели, было бы целесообразно вызывать как OnPropertyChanged(Foo), так и OnPropertyChanged(Bar) в вашей модели представления при изменении значения. Foo.

Другой альтернативой является использование событий между Model и ViewModel для обновления тех значений в ViewModel, которые требуют обновления. Если, как вы говорите, уведомление требуется «только в первый раз», то выполнение ручного однократного обновления для некоторого триггера также должно работать.

10 голосов
/ 03 августа 2011

Это очень распространенная проблема при работе с MVVM, INotifyPropertyChanged не является специфичной для WPF, так как является частью System.ComponentModel, поэтому нет необходимости добавлять какие-либо ссылки на WPF в ваше решение.

Если вы внедрите INofityPropertyChanged в своей модели, она может сохранить намного больше кодов во ViewModel (свойства прокси).Таким образом, допустимо, что ваша модель использует INotifyPropertyChanged.

9 голосов
/ 03 августа 2011

Иногда допустимо, чтобы модель реализовывала интерфейс INotifyPropertyChanged.

Например, если модель имеет много свойств, которые нужно визуализировать, и вы хотите избежать реализации большого количества кода (проксиСвойства) в viewmodel для предоставления таких свойств модели.

Посмотрите на http://msdn.microsoft.com/en-us/magazine/ff798279.aspx

3 голосов
/ 10 апреля 2012

Это классический аргумент между «чистыми» кодировщиками MVVM и другими.

Я склонен идти по книгам, когда могу, потому что в большинстве случаев это имеет смысл.Однако в некоторых сценариях импровизация кода в соответствии с потребностями уменьшает количество дублирующегося кода.

В вашем случае вы можете прочитать XML в класс модели и либо скопировать класс модели в модель представленияили скопируйте нужные свойства из модели в модель представления.Таким образом, у вас есть контроль над обновлением пользовательского интерфейса / модели.Если вы следуете первому подходу, вам нужно реализовать Inotifypropertyolated в вашем классе модели, и это приемлемо.

Сказав, что я буду стараться изо всех сил следовать второму подходу, потому что это даст мне точный контроль над всемисвойства, которые отображаются / обрабатываются в представлении.Кроме того, я буду чувствовать себя намного лучше, если не нарушу паттерн MVVM.

3 голосов
/ 03 августа 2011

Я не уверен, что вы имеете в виду.В ВМ вы можете иметь либо INotifyPropertyChanged, либо DependencyProperty-es (в этом случае ВМ должна быть производной от DependencyObject).Не имеет смысла иметь оба.Также не имеет смысла иметь ни одного из них.

В модели вы можете делать все, что захотите.Возможность стрелять / получать события хороша, но не всегда вы можете положиться на них.В основном модель зависит от исходных данных и связанных с ними материалов, в то время как модель представления загружает интерфейс модели с уровнем представления.Поскольку WPF работает с событиями, не менее виртуальная машина должна обеспечить некоторый механизм уведомления.

...