В модели MVVM модель должна реализовывать интерфейс INotifyPropertyChanged?

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

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

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

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

Ответ 1

Реализация 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.

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

Ответ 2

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

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

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

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

Ответ 3

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

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

Ответ 4

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

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

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

Ответ 5

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

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

Ответ 6

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

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

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

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