Wpf - inotifypropertychanged або dependencyproperty в viewmodel - data-binding - architecture, code

При реалізації ViewModel в додатку WPF для архітектури Model-View-ViewModel, схоже, є два основні варіанти, як зробити його прив'язували до даних. Я бачив реалізації, які використовують DependencyProperty для властивостей, з якими View зв'язується, і я бачив, що ViewModel реалізує INotifyPropertyChanged.

Моє питання в тому, коли я повинен віддати перевагу іншому? Чи існують відмінності в продуктивності? Це дійсно хороша ідея надати залежності ViewModel для WPF? Що ще мені потрібно враховувати при прийнятті дизайнерського рішення?

  1. DependencyObjects не позначене як Серіалізуемое
  2. Клас DependencyObject переопределяет і ущільнює методи Equals () і GetHashCode ()
  3. У DependencyObject є схожість потоків - доступ до нього можливий тільки в потоці, на якому він був створений

Згідно керівництву по ефективності WPF, DependencyObjects безумовно працюють краще, ніж POCOs, які реалізують INotifyPropertyChanged:

Вибір повністю заснований на вашій бізнес-логікою і рівні абстракції призначеного для користувача інтерфейсу. Якщо ви не хочете гарного поділу, то DP буде працювати на вас.

DependencyProperties буде застосовуватися, головним чином, на рівні VisualElements, тому не буде гарною ідеєю, якщо ми створимо багато DP для кожного з наших бізнес-вимог. Також для DP більш висока вартість, ніж INotifyPropertyChanged. Коли ви розробляєте WPF / Silverlight, спробуйте повністю налаштувати інтерфейс і ViewModel, щоб в будь-який момент часу ми могли змінювати елементи макета і призначеного для користувача інтерфейсу (на основі теми і стилів)

З точки зору виразності я повністю насолоджуюся використанням властивостей залежностей і зменшується при думці про INotifyPropertyChanged. Крім імен властивостей string і можливих витоків пам'яті через підписку на події, INotifyPropertyChanged є набагато більш явним механізмом.

Властивості залежностей мають на увазі «коли це, зробіть це», використовуючи легко зрозумілі статичні метадані. Це декларативний підхід, який отримує мій голос за елегантність.

INotifyPropertyChanged при використанні також дає вам можливість додати більше логіки в код ваших геттеров і настроювач ваших властивостей.

У вашому getter і setter --- все, що ви можете зробити, це просто викликати SetValue і GetValue відповідно, b / c в інших частинах фреймворка, який не викликається getter / setter, замість цього він безпосередньо викликає SetValue, GetValue, тому ваша логіка властивості не буде Надійно виконуватися.

За допомогою функції INotifyPropertyChanged визначте подія:

А потім просто використовуйте будь-яку логіку в своєму коді, потім телефонуйте:

Це може бути в Геттера / сетера або в іншому місці.

Властивості залежностей призначені для підтримки прив'язки (як цілі) до елементів призначеного для користувача інтерфейсу, а не як джерела прив'язки даних, в цьому полягає INotifyProperty. З чистою точки зору ви не повинні використовувати DP в ViewModels.

«Щоб стати джерелом прив'язки, властивість не обов'язково має бути властивістю залежності, ви можете використовувати будь-яку властивість CLR як джерело прив'язки. Однак для того, щоб стати об'єктом прив'язки, властивість має бути Залежний властивість. Для того щоб одностороння або двостороння прив'язка була ефективною, властивість source має підтримувати повідомлення про зміни, які поширюються на систему прив'язки і, отже, на ціль. Для користувальницьких джерел прив'язки CLR це означає, що властивість має підтримувати INotifyPropertyChanged. Колекції повинні підтримувати INotifyCollectionChanged. "

Всі об'єкти залежностей не можуть бути серіалізовані (це може перешкодити використанню ViewModels і DTO (POCO).

Існують відмінності між DP в Silverlight в порівнянні з WPF.

Мені теж довелося розглянути це рішення недавно.

Я виявив, що механізм INotifyPropertyChanged підходить для моїх потреб краще, тому що це дозволило мені приклеїти мій графічний інтерфейс до існуючої структури бізнес-логіки без дублювання стану. Структура, яку я використовував, мала свій власний шаблон спостерігача, і було легко перенести один рівень повідомлення на наступний. У мене просто був клас, який реалізував інтерфейс спостерігача з моєї бізнес-логіки і інтерфейсу INotifyPropertyChanged.

За допомогою DP ви не можете визначити бекенда, який зберігає стан самостійно. Мені довелося б .net кешувати копію кожного елемента стану, до якого я прив'язувався. Це здавалося непотрібним накладними витратами - мій стан велике і складно.

Таким чином, тут я знайшов INotifyPropertyChanged краще для відображення властивостей з бізнес-логіки в GUI.

Говорячи там, де мені потрібен віджет призначеного для користувача GUI, щоб виставити властивість, а для змін цієї властивості вплинути на інші віджети GUI, DP довів просте рішення.

Тому там я знайшов DP корисним для GUI для повідомлення GUI.

Це дійсно хороша ідея надати залежності ViewModel для WPF?

NET 4.0 матиме System.Xaml.dll, тому вам не доведеться залежати від довільної структури, щоб використовувати його. Див. Повідомлення Роба Релі про його сеансі PDC.

XAML - це мова для опису об'єктів, а WPF - це структура, описаними об'єктами якої є елементи призначеного для користувача інтерфейсу.

Їх зв'язок схожа на C #, мова опису логіки і .NET, структуру, яка реалізує певні види логіки.

Мета XAML - це декларативні графи об'єктів. Технології W * F є відмінними кандидатами для цієї парадигми, але XAML існує незалежно від них.

XAML і вся система залежностей були реалізовані як окремі стеки для WF і WPF, можливо, щоб використовувати досвід різних команд, не створюючи залежності (без каламбуру) між ними.

Здається, що властивості залежностей повинні використовуватися в елементах управління, які ви створюєте, таких як кнопки. Щоб використовувати властивості в XAML і використовувати всі функції WPF, ці властивості повинні мати властивості залежностей.

Однак ваш ViewModel краще використовувати INotifyPropertyChanged. Використання INotifyPropertyChanged дасть вам можливість мати логіку getter / setter, якщо вам потрібно.

Я рекомендую перевірити версію Josh Smith базового класу для ViewModel, яка вже реалізує INotifyPropertyChanged:

Я думаю, що це відмінний приклад того, як робити ViewModel.

Я думаю, що DependencyProperty і INotifyPropertyChanged використовуються для двох різних речей в Binding: перший для включення властивості як об'єкта прив'язки і отримання введення від іншої властивості (використовуйте, щоб встановити властивість), останній Коли ви хочете, щоб значення властивості використовувалося як джерело прив'язки (ім'я в вираженні Binding Path Expression). Таким чином, вибір просто технічний.

Властивості залежностей - це клей створення призначеного для користувача елементу управління. Якщо ви зацікавлені в використанні Intelli-sense, щоб показати свої властивості у вікні властивостей під час розробки XAML, ви повинні використовувати властивості Dependency. INPC ніколи не буде показувати властивість у вікні властивостей під час розробки.

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

Є тільки одна річ, чому потрібно вміти підготувати DependencyObject - Binding буде працювати краще. Просто спробуйте приклад з ListBox і TextBox. заповніть список даними з властивості INotifyPropertyChanged і DependencyProperty і відредагуйте поточний елемент з TextBox.