Вопрос

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

Мой вопрос: когда мне отдавать предпочтение одному? Есть ли различия в производительности? Это действительно хорошая идея, чтобы дать зависимости ViewModel для WPF? Что еще нужно учитывать, когда принимаете проектное решение?

Это было полезно?

Решение

Кент написал интересный блог на эту тему: Просмотреть модели: POCOs против DependencyObjects .

Краткое резюме.

<Ол>
  • DependencyObjects не помечены как сериализуемый
  • Класс DependencyObject переопределяет и запечатывает Equals () и Методы GetHashCode ()
  • DependencyObject имеет сходство с потоками & # 8211; к нему можно получить доступ только на нити, на которой это было создано
  • Я предпочитаю подход POCO. Базовый класс для PresentationModel (он же ViewModel), который реализует интерфейс INotifyPropertyChanged, можно найти здесь: http://compositeextensions.codeplex.com

    Другие советы

    Выбор полностью зависит от вашей бизнес-логики и уровня абстракции пользовательского интерфейса. Если вы не хотите хорошего разделения, DP будет работать для вас.

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

    См. также этот пост - https: // stackoverflow.com/questions/275098/what-applications-could-i-study-to-understand-datamodel-view-viewmodel . Ссылка содержит много ссылок на шаблон Model-View-ViewModel, который очень важен для этого обсуждения.

    С точки зрения выразительности мне очень нравится использовать свойства зависимостей и раздражаться при мысли о INotifyPropertyChanged . Помимо имен свойств string и возможных утечек памяти из-за подписки на события, INotifyPropertyChanged представляет собой гораздо более явный механизм.

    Свойства зависимости подразумевают "когда это так, сделайте это" используя понятные статические метаданные. Это декларативный подход, который получает мой голос за элегантность.

    INotifyPropertyChanged при использовании также дает вам возможность добавлять больше логики в код ваших получателей и установщиков ваших свойств.

    DependencyProperty пример:

    public static DependencyProperty NameProperty = DependencyProperty.Register( "Name", typeof( String), typeof( Customer ) );
    
    public String Name
    {
        set { SetValue( NameProperty, value ); }
        get { return ( String ) GetValue( NameProperty ); }
    }
    

    В ваших getter и setter --- все, что вы можете сделать, это просто вызвать SetValue и GetValue соответственно, b / c, в других частях фреймворка getter / setter не вызывается, вместо этого он напрямую вызывает SetValue, GetValue, так что ваш логика свойств не будет надежно выполнена.

    С помощью INotifyPropertyChanged определите событие:

    public event PropertyChangedEventHandler PropertyChanged;
    

    А потом просто используйте любую логику в любом месте вашего кода, затем вызовите:

    // ...
    // Something cool...
    // ...
    
    if( this.PropertyChanged != null )
    {
        PropertyChanged( this, new PropertyChangedEventArgs( "Name" ) );
    }
    
    // More cool stuff that will reliably happen...
    

    Это может быть в методе получения / установки или где-либо еще.

    Свойства зависимостей предназначены для поддержки привязки (в качестве цели) к элементам пользовательского интерфейса, а не к привязке источника к данным. Именно здесь INotifyProperty. С чистой точки зрения не следует использовать DP в ViewModels.

    " чтобы быть источником привязки, свойство не обязательно должно быть свойством зависимости; Вы можете использовать любое свойство CLR в качестве источника привязки. Однако для того, чтобы быть целью привязки, свойство должно быть свойством зависимости. Чтобы односторонняя или двусторонняя привязка была эффективной, свойство источника должно поддерживать уведомления об изменениях, которые распространяются на систему привязки и, следовательно, на цель. Для пользовательских источников привязки CLR это означает, что свойство должно поддерживать INotifyPropertyChanged. Коллекции должны поддерживать INotifyCollectionChanged. & Quot;

    Все объекты зависимостей не могут быть сериализованы (это может затруднить использование ViewModels и DTO (POCO).

    Есть различия между DP в Silverlight по сравнению с WPF.

    http://msdn.microsoft.com /en-us/library/cc221408(v=VS.95).aspx

    http://msdn.microsoft.com/en -us / библиотека / cc903933 (VS.95) .aspx

    Я тоже должен был рассмотреть это решение недавно.

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

    С помощью DP вы не можете определить серверную часть, которая хранит состояние самостоятельно. Мне бы пришлось позволить .net кешировать копию каждого элемента состояния, к которому я привязан. Это казалось ненужными накладными расходами - мое состояние большое и сложное.

    Так что здесь я нашел INotifyPropertyChanged лучше для предоставления свойств бизнес-логики графическому интерфейсу.

    Это, как говорится, когда мне нужен пользовательский виджет 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, вероятно, для использования опыта различных команд без создания зависимости (без каламбура) между ними.

    Свойства зависимостей являются связующим звеном создания пользовательских элементов управления. Если вы заинтересованы в использовании 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 ...} для установки свойства) последний, когда вы хотите, чтобы значение свойства использовалось в качестве источника привязки (имя в выражении пути привязки). Так что выбор чисто технический.

    Есть только одна причина, почему предпочтительнее DependencyObject - привязка будет работать лучше. Просто попробуйте пример с ListBox и TextBox , заполните список данными из свойства INotifyPropertyChanged и DependencyProperty и отредактируйте текущий элемент из TextBox ...

    Если вы хотите выставить свойства другим элементам управления, вы должны использовать свойства зависимости ... Но удачи, потому что им требуется время, чтобы выяснить ...

    scroll top