В модели MVVM модель должна реализовывать интерфейс INotifyPropertyChanged?
У меня есть четкое представление о View
а также ViewModel
в шаблоне MVVM. Я планирую реализовать шаблон MVVM в моем приложении. У меня проблема с моделью. У меня есть XML-файл, который анализируется, и информация отображается в представлении.
Мне нужно получать уведомления об изменениях в модели только в первый раз. Отныне по требованию меня нужно уведомить.
Так как же реализовать модель?
Должен ли я реализовать INotifyPropertyChanged
Интерфейс в классе модели также? (Я читал, что модель не должна реализовывать INotifyPropertyChanged
интерфейс, так как он специфичен для WPF)
6 ответов
Внедрение INotifyPropertyChanged
в моделях вполне приемлемо -
Как правило, модель реализует средства, облегчающие привязку к представлению. Обычно это означает, что он поддерживает уведомление об изменении свойства и коллекции через
INotifyPropertyChanged
а такжеINotifyCollectionChanged
интерфейсы. Классы моделей, которые представляют коллекции объектов, как правило, являются производными отObservableCollection<T>
класс, который обеспечивает реализациюINotifyCollectionChanged
интерфейс.
Хотя вам решать, хотите ли вы этот тип реализации или нет, но помните -
Что если в ваших модельных классах не реализованы необходимые интерфейсы?
Иногда вам нужно будет работать с объектами модели, которые не реализуют
INotifyPropertyChanged
,INotifyCollectionChanged
,IDataErrorInfo
, или жеINotifyDataErrorInfo
интерфейсы. В этих случаях модели представления может потребоваться обернуть объекты модели и предоставить необходимые свойства представлению. Значения этих свойств будут предоставлены непосредственно объектами модели. Модель представления будет реализовывать необходимые интерфейсы для свойств, которые она предоставляет, чтобы представление могло легко привязать к ним данные.
Взято с - http://msdn.microsoft.com/en-us/library/gg405484(PandP.40).aspx
Я работал в некоторых проектах, где мы не реализовали INotifyPropertyChanged
в наших моделях и из-за этого мы столкнулись с множеством проблем; ненужное дублирование свойств было необходимо в ВМ, и в то же время нам пришлось обновить базовый объект (с обновленными значениями) перед передачей их в BL/DL.
Вы столкнетесь с проблемами, особенно если вам нужно работать с коллекцией объектов вашей модели (скажем, в редактируемой сетке или списке) или со сложными моделями; объекты модели не будут обновляться автоматически, и вам придется управлять всем этим в вашей виртуальной машине.
Стандартный подход MVVM заключается в реализации INotifyPropertyChanged
только на ViewModel. Цель состоит в том, чтобы обновить соответствующие привязки в представлении, когда что-то изменяется в модели представления.
Однако это предназначается для изменений в ViewModel с помощью View. То есть, когда вы меняете значение в TextBox
, INotifyPropertyChanged
Реализация на ViewModel обновит связанные привязки, поэтому View обновляется корректно.
Он не охватывает изменения, внесенные в модель внешним источником, например изменения базы данных или другой интерфейс. Пока все модификации данных происходят из View, ViewModel должен знать обо всех изменениях и знать, что обновлять. Например, если вы знаете, что изменение переменной Foo
на вашей модели также изменит значение Bar
на вашей модели, было бы целесообразно назвать оба OnPropertyChanged(Foo)
а также OnPropertyChanged(Bar)
в вашей ViewModel при изменении значения Foo
,
Другой альтернативой является использование событий между Model и ViewModel, чтобы обновить те значения в ViewModel, которые требуют обновления. Если, как вы говорите, уведомление требуется "только в первый раз", то выполнение ручного однократного обновления для некоторого триггера также должно работать.
Это очень распространенная проблема при работе с MVVM, INotifyPropertyChanged
не является специфичным для WPF, так как является частью System.ComponentModel
поэтому нет необходимости добавлять какие-либо ссылки на WPF в ваше решение.
Если вы будете реализовывать INofityPropertyChanged
в вашей модели это может сохранить намного больше кода в ViewModel(Proxy Properties). Так что приемлемо для модели иметь INotifyPropertyChanged
,
Иногда приемлемо, чтобы модель реализовала INotifyPropertyChanged
интерфейс.
Например, если модель имеет много свойств, которые нужно визуализировать, и вы хотите избежать внедрения большого количества кода (свойств прокси) в модель представления для предоставления таких свойств модели.
Посмотрите на http://msdn.microsoft.com/en-us/magazine/ff798279.aspx
Это классический аргумент между "чистыми" кодировщиками MVVM и другими.
Я стараюсь ходить по книгам, когда могу, потому что в большинстве случаев это имеет смысл. Тем не менее, в определенных сценариях импровизация кода в соответствии с потребностями уменьшает количество дублирующегося кода.
В вашем случае вы можете прочитать XML в класс модели и либо скопировать класс модели в модель представления, либо скопировать требуемые свойства из модели в модель представления. Таким образом, у вас есть контроль за обновлением пользовательского интерфейса / модели. Если вы следуете первому подходу, вам нужно внедрить свойство Inotifypropertyolated в классе модели, и это приемлемо.
Сказав, что я буду стараться изо всех сил, чтобы следовать второму подходу, потому что это дало бы мне точный контроль над всеми свойствами, которые отображаются / манипулируются в представлении. Кроме того, я буду чувствовать себя намного лучше, если не нарушу паттерн MVVM.
Я не уверен, что вы имеете в виду. В виртуальной машине вы можете иметь INotifyPropertyChanged
или DependencyProperty-es (в этом случае виртуальная машина должна быть производной от DependencyObject
). Не имеет смысла иметь оба. Также не имеет смысла иметь ни одного из них.
В модели вы можете делать все, что захотите. Возможность стрелять / получать события хороша, но не всегда вы можете положиться на них. В основном, модель зависит от исходных данных и связанных элементов, в то время как модель представления загружает интерфейс модели с уровнем представления. Поскольку WPF работает с событиями, по крайней мере, виртуальная машина должна обеспечивать некоторый механизм уведомления.