При реализации ViewModel в WPF-приложении с архитектурой Model-View-ViewModel кажется, что существует два основных способа сделать его доступным для данных. Я видел реализации, которые используют DependencyProperty
для свойств, с которыми будет связываться View, и INotifyPropertyChanged
вместо этого я видел реализацию ViewModel .
Мой вопрос: когда я должен предпочесть одно другому? Есть ли различия в производительности? Это действительно хорошая идея, чтобы дать зависимости ViewModel для WPF? Что еще нужно учитывать при принятии проектного решения?
INotifyPropertyChanged
.Ответы:
Кент написал интересный блог на эту тему: View Models: POCOs против DependencyObjects .
Краткое содержание:
Я предпочитаю подход POCO. Базовый класс для PresentationModel (он же ViewModel), который реализует интерфейс INotifyPropertyChanged, можно найти здесь: http://compositeextensions.codeplex.com
источник
Согласно руководству по производительности WPF, DependencyObjects определенно работают лучше, чем POCO, которые реализуют INotifyPropertyChanged:
http://msdn.microsoft.com/en-us/library/bb613546.aspx
источник
Выбор полностью зависит от вашей бизнес-логики и уровня абстракции пользовательского интерфейса. Если вы не хотите хорошего разделения, DP будет работать для вас.
DependencyProperties будет применяться в основном на уровне VisualElements, поэтому не будет хорошей идеей, если мы создадим много DP для каждого из наших бизнес-требований. Также для DP существует более высокая стоимость, чем для INotifyPropertyChanged. Когда вы разрабатываете WPF / Silverlight, постарайтесь спроектировать UI и ViewModel полностью раздельно, чтобы в любой момент мы могли изменить элементы управления Layout и UI (на основе темы и стилей).
См. Также этот пост - /programming/275098/what-applications-could-i-study-to-understand-datamodel-view-viewmodel . Ссылка имеет много ссылок на шаблон Model-View-ViewModel, который очень важен для этого обсуждения.
источник
С точки зрения выразительности, я полностью наслаждаюсь использованием свойств зависимости и съеживаюсь при мысли
INotifyPropertyChanged
. Помимоstring
имен свойств и возможных утечек памяти из-за подписки на события,INotifyPropertyChanged
существует гораздо более явный механизм.Свойства зависимостей подразумевают «когда это, делай это», используя понятные статические метаданные. Это декларативный подход, который получает мой голос за элегантность.
источник
[CallerMemberName]
.INotifyPropertyChanged
при использовании также дает вам возможность добавлять больше логики в код ваших получателей и установщиков ваших свойств.DependencyProperty
пример:В ваших методах получения и установки --- все, что вы можете сделать, это просто вызвать SetValue и GetValue, соответственно, b / c, в других частях платформы getter / setter не вызывается, вместо этого он напрямую вызывает SetValue, GetValue, так что логика вашего свойства не будет надежно исполняться.
С
INotifyPropertyChanged
, определить событие:А затем просто используйте любую логику в вашем коде, затем вызовите:
Это может быть в методе получения / установки или где-либо еще.
источник
Свойства зависимостей предназначены для поддержки привязки (в качестве цели) к элементам пользовательского интерфейса, а не к привязке источника к данным, вот где INotifyProperty приходит. С чистой точки зрения, вы не должны использовать DP в ViewModels.
«Чтобы быть источником привязки, свойство не обязательно должно быть свойством зависимости; вы можете использовать любое свойство CLR в качестве источника привязки. Однако для того, чтобы стать целью привязки, свойство должно быть свойство зависимости. Для того чтобы односторонняя или двусторонняя привязка была эффективной, свойство источника должно поддерживать уведомления об изменениях, которые распространяются на систему привязки и, следовательно, на цель. Для пользовательских источников привязки CLR это означает, что свойство должно поддерживать INotifyPropertyChanged. Коллекции должны поддерживать INotifyCollectionChanged. "
Все объекты зависимостей не могут быть сериализованы (это может затруднить использование ViewModels и DTO (POCO).
Есть различия между DP в Silverlight по сравнению с WPF.
http://msdn.microsoft.com/en-us/library/cc221408(v=VS.95).aspx
http://msdn.microsoft.com/en-us/library/cc903933(VS.95).aspx
источник
Я тоже должен был рассмотреть это решение недавно.
Я обнаружил, что механизм INotifyPropertyChanged лучше соответствует моим потребностям, потому что он позволяет мне приклеивать мой графический интерфейс к существующей инфраструктуре бизнес-логики без дублирования состояния. У структуры, которую я использовал, была своя собственная схема наблюдателя, и было легко перенаправить один уровень уведомления на следующий. У меня просто был класс, который реализовал интерфейс наблюдателя из моей бизнес-логики и интерфейс INotifyPropertyChanged.
С DP вы не можете определить бэкэнд, который хранит состояние самостоятельно. Мне пришлось бы разрешить .net кешировать копию каждого элемента состояния, к которому я привязан. Это казалось ненужными накладными расходами - мое состояние большое и сложное.
Поэтому здесь я обнаружил, что INotifyPropertyChanged лучше для предоставления свойств из бизнес-логики графическому интерфейсу.
Тем не менее, когда мне был нужен пользовательский виджет GUI для предоставления свойства и для того, чтобы изменения этого свойства влияли на другие виджеты GUI, DP доказал простое решение.
Так что я нашел DP полезным для GUI для уведомления GUI.
источник
.NET 4.0 будет иметь System.Xaml.dll, поэтому вам не придется использовать зависимость от произвольной среды для ее использования. Посмотрите пост Роба Рельеа о его сессии PDC.
Мой дубль
XAML - это язык для описания объектов, а WPF - это фреймворк, чьи описанные объекты являются элементами пользовательского интерфейса.
Их отношения похожи на C #, язык для описания логики, и .NET, каркас, который реализует определенные виды логики.
Цель XAML - декларативные графы объектов. Технологии W * F являются отличными кандидатами на эту парадигму, но XAML существует независимо от них.
XAML и вся система зависимостей были реализованы в виде отдельных стеков для WF и WPF, вероятно, для использования опыта различных команд без создания зависимости (без каламбура) между ними.
источник
Свойства зависимостей являются связующим звеном создания пользовательских элементов управления. Если вы заинтересованы в использовании Intelli-sense для отображения своих свойств в окне свойств во время разработки XAML, вы должны использовать свойства зависимости. INPC никогда не будет показывать свойство в окне свойств во время разработки.
источник
Кажется, что свойства зависимости должны использоваться в создаваемых вами элементах управления, таких как кнопки. Чтобы использовать свойства в XAML и использовать все функции WPF, эти свойства должны иметь свойства зависимости.
Тем не менее, ваша ViewModel лучше использовать INotifyPropertyChanged. Использование INotifyPropertyChanged даст вам возможность иметь логику получения / установки, если вам нужно.
Я рекомендую проверить версию базового класса Джоша Смита для ViewModel, которая уже реализует INotifyPropertyChanged:
http://joshsmithonwpf.wordpress.com/2007/08/29/a-base-class-which-implements-inotifypropertychanged/
Я думаю, что это отличный пример того, как сделать ViewModel.
источник
Я думаю, что DependencyProperty и INotifyPropertyChanged используются для двух разных вещей в Binding: первый для включения свойства быть целью привязки и получения ввода от другого свойства (используйте {Binding ...} для установки свойства), последний когда вы хотите, чтобы значение свойства использовалось в качестве источника привязки (имя в выражении пути привязки). Так что выбор чисто технический.
источник
Я предпочитаю более прямой подход, о котором я писал в разделе «Модель представления без INotifyPropertyChanged» . Используя альтернативу привязке данных, вы можете привязать напрямую к свойствам CLR без какого-либо бухгалтерского кода. Вы просто пишете старый код .NET в своей модели представления, и он обновляется при изменении вашей модели данных.
источник
INotifyPropertyChanged
,PropertyDescriptor
используются, что вызывает утечки памятиЕсть только одна причина, почему предпочтение
DependencyObject
- Binding будет работать лучше. Просто попробуйте пример сListBox
иTextBox
, заполните список данными изINotifyPropertyChanged
свойства vs.DependencyProperty
и отредактируйте текущий элемент изTextBox
...источник
Если вы хотите представить свойства другим элементам управления, вы должны использовать свойства зависимости ... Но удачи, потому что они требуют времени, чтобы выяснить ...
источник