INotifyPropertyChanged vs. DependencyProperty in ViewModel

lors de la mise en œuvre du ViewModel dans une architecture Model-View-ViewModel application WPF il semble y avoir deux choix majeurs pour le rendre databindable. J'ai vu des implémentations qui utilisent DependencyProperty pour des propriétés contre lesquelles la vue va se lier et j'ai vu le ViewModel implémenter INotifyPropertyChanged à la place.

ma question est quand devrais-je préférer l'un à l'autre? Existe-il des écarts de performances? Est-ce vraiment une bonne idée de donner à la ViewModel dépendances à WPF? Que dois-je prendre en considération lorsque je prends la décision de concevoir?

341
demandé sur lokusking 2008-11-15 00:33:17
la source

14 ответов

Kent a écrit un blog intéressant sur ce sujet: View Models: POCOs versus DependencyObjects .

bref résumé:

  1. les objets de dépendance ne sont pas marqués comme serialisable
  2. la classe DependencyObject dépasse et scelle les égaux () et Méthodes GetHashCode ()
  3. un objet Dependencyob a une affinité de thread – il ne peut être accédé sur le fil sur lequel il était created

je préfère l'approche POCO. Une classe de base pour PresentationModel (alias ViewModel) qui implémente l'interface INotifyPropertyChanged peut être trouvée ici: http://compositeextensions.codeplex.com

205
répondu jbe 2016-02-08 13:05:11
la source

selon le WPF performance guide, DependencyObjects perform definitely better than POCOs that implement INotifyPropertyChanged:

http://msdn.microsoft.com/en-us/library/bb613546.aspx

36
répondu James Ashley 2010-11-03 19:45:21
la source

le choix est totalement basé sur votre logique d'entreprise et votre niveau D'abstraction de L'interface utilisateur. Si vous ne voulez pas une bonne séparation, alors DP fonctionnera pour vous.

DependencyProperties sera applicable principalement à la VisualElements niveau afin de ne pas être une bonne idée si nous créer beaucoup de DPs pour chacun de nos exigences de l'entreprise. Il y a aussi un coût plus élevé pour DP qu'un INotifyPropertyChanged. Lorsque vous concevez un WPF / Silverlight essayer de concevoir L'interface utilisateur et le modèle de vue totalement séparé ainsi qu'à tout moment nous pouvons changer la mise en page et les contrôles de L'interface utilisateur (basés sur le thème et les Styles)

Consultez ce post aussi - https://stackoverflow.com/questions/275098/what-applications-could-i-study-to-understand-datamodel-view-viewmodel . Le lien a beaucoup de référence au modèle-View-ViewModel, ce qui est très pertinent pour cette discussion.

26
répondu Jobi Joy 2017-05-23 15:34:51
la source

du point de vue de l'expressivité, j'aime beaucoup utiliser les propriétés de dépendance et frémir à la pensée de INotifyPropertyChanged . Outre les noms de propriétés string et les fuites de mémoire possibles en raison de l'abonnement à un événement, INotifyPropertyChanged est un mécanisme beaucoup plus explicite.

propriétés de Dépendance implique "quand ceci, fais cela" à l'aide de facile à comprendre les métadonnées statiques. C'est une approche déclarative qui obtient mon vote pour l'élégance.

19
répondu Bryan Watts 2008-11-16 02:41:22
la source

INotifyPropertyChanged vous donne également la possibilité d'ajouter plus de logique dans le code de votre getters et définition de vos propriétés.

DependencyProperty exemple:

public static DependencyProperty NameProperty = DependencyProperty.Register( "Name", typeof( String), typeof( Customer ) );

public String Name
{
    set { SetValue( NameProperty, value ); }
    get { return ( String ) GetValue( NameProperty ); }
}

dans votre getter et setter - - - tout ce que vous pouvez faire est simplement appeler SetValue et GetValue respectivement, b/C dans d'autres parties du cadre le getter/setter n'est pas appelé, à la place il appelle directement SetValue, GetValue, de sorte que votre logique de propriété ne serait pas exécuté de manière fiable.

avec INotifyPropertyChanged , définissez un événement:

public event PropertyChangedEventHandler PropertyChanged;

et puis tout simplement avoir n'importe quelle logique n'importe où dans votre code, puis appeler:

// ...
// Something cool...
// ...

if( this.PropertyChanged != null )
{
    PropertyChanged( this, new PropertyChangedEventArgs( "Name" ) );
}

// More cool stuff that will reliably happen...

cela pourrait être dans un getter/setter, ou n'importe où ailleurs.

16
répondu Adam 2011-03-25 16:38:53
la source

les propriétés de dépendance sont destinées à soutenir la liaison (en tant que cible) sur les éléments D'assurance-chômage pas comme une source de liaison de données, c'est là où INotifyProperty entre en jeu. D'un point de vue pur, vous ne devriez pas utiliser DP sur des modèles de vue.

" pour être la source d'une binding, une propriété n'a pas besoin d'être une propriété de dépendance; vous pouvez utiliser n'importe quelle propriété CLR comme source de binding. Toutefois, afin d'être la cible d'une liaison, la propriété doit être une dépendance propriété. Pour qu'une obligation unidirectionnelle ou bidirectionnelle soit efficace, la propriété source doit supporter les notifications de changement qui se propagent au système d'obligation et donc à la cible. Pour custom CLR binding sources, cela signifie que la propriété doit supporter INotifyPropertyChanged. Les Collections devraient soutenir Inotifycollection Modified."

tous les objets de dépendance ne peuvent pas être sérialisés (cela pourrait entraver l'utilisation des modèles de vue et des DTO (POCO).

il y a différences entre le PDD de Silverlight et celui de WPF.

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

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

16
répondu Nick Hermans 2011-11-09 14:07:49
la source

moi aussi j'ai dû tenir compte de cette décision récemment.

j'ai trouvé que le mécanisme INotifyPropertyChanged mieux adapté à mes besoins parce qu'il m'a permis de coller mon GUI à un cadre existant de logique d'affaires sans dupliquer l'état. Le cadre que j'utilisais avait son propre modèle d'observateur et il était facile de transmettre un niveau de notification au suivant. J'ai simplement eu une classe qui a mis en œuvre l'interface observateur à partir de mon cadre logique d'entreprise et le INotifyPropertyChanged interface.

avec DP vous ne pouvez pas définir le backend qui stocke l'état vous-même. J'aurais dû laisser .net mettre en cache une copie de chaque élément de l'état que je Liais. Cela a semblé comme un overhead inutile - mon état est grand et compliqué.

donc ici j'ai trouvé INotifyPropertyChanged mieux pour exposer les propriétés de la logique d'affaires à GUI.

cela étant dit où j'avais besoin d'un widget GUI personnalisé pour exposer une propriété et pour des changements à cette propriété d'affecter d'autres widgets GUI DP prouvé la solution simple.

donc là J'ai trouvé DP utile pour GUI à GUI notification.

7
répondu morechilli 2008-11-24 20:16:32
la source

est-ce vraiment une bonne idée de donner les dépendances ViewModel à WPF?

.NET 4.0 aura un système.XAML.dll, donc vous n'aurez pas à prendre une dépendance sur l'arbitraire d'un cadre à l'utiliser. Voir Rob Relyea post sur son PDC session.

de Mon point de vue

XAML est un langage pour décrire des objets, et WPF est un cadre dont la description les objets sont des éléments UI.

leur relation est similaire à C#, un langage pour décrire la logique, et .NET, un cadre qui implémente des types particuliers de logique.

le but de XAML est des graphiques d'objet déclaratifs. Les technologies W*F sont d'excellents candidats pour ce paradigme, mais XAML existe indépendamment d'eux.

XAML et l'ensemble du système de dépendances ont été implémentés comme des piles séparées pour WF et WPF, probablement pour tirer parti l'expérience de différentes équipes sans créer de dépendance (sans jeu de mots) entre elles.

6
répondu Bryan Watts 2008-11-15 12:25:07
la source

il semble que les propriétés de dépendance doivent être utilisées dans les contrôles que vous créez tels que les boutons. Pour utiliser des propriétés dans XAML et utiliser toutes les caractéristiques WPF, ces propriétés doivent posséder des propriétés de dépendance.

cependant, votre modèle de vue est mieux en utilisant INotifyPropertyChanged. Utiliser INotifyPropertyChanged vous donnera la capacité d'avoir la logique getter/setter si vous en avez besoin.

je recommande de vérifier la version de Josh Smith d'une classe de base pour un modèle de vue qui implémente déjà INotifyPropertyChanged:

http://joshsmithonwpf.wordpress.com/2007/08/29/a-base-class-which-implements-inotifypropertychanged /

je pense que c'est un excellent exemple de comment faire un ViewModel.

4
répondu timothymcgrath 2009-03-25 04:59:11
la source

je pense que DependencyProperty et INotifyPropertyChanged sont utilisés pour deux choses différentes dans Binding : la première pour permettre à une propriété d'être la cible d'une binding et de recevoir l'input d'une autre propriété (utiliser {Binding ...} pour définir la propriété), la dernière lorsque vous voulez que la valeur d'une propriété soit utilisée comme source d'une liaison (nom dans l'Expression chemin de liaison). Le choix est donc purement technique.

4
répondu Domnik 2010-09-02 22:37:07
la source
Les propriétés de dépendance

sont le ciment de la création de contrôle personnalisé. Si vous êtes intéressé à utiliser Intelli-sense pour afficher vos propriétés dans la fenêtre Propriétés au moment de la conception XAML, vous devez utiliser des propriétés de dépendances. INPC ne montrera jamais une propriété dans la fenêtre de la propriété au moment de la conception.

4
répondu John Peters 2014-10-29 00:04:28
la source

je préfère une approche plus directe, sur laquelle j'ai blogué dans modèle de présentation sans INotifyPropertyChanged . En utilisant une alternative à la liaison de données, vous pouvez vous lier directement aux propriétés CLR sans aucun code comptable. Vous n'avez qu'à écrire un simple vieux code.net dans votre modèle de vue, et il est mis à jour lorsque votre modèle de données change.

3
répondu Michael L Perry 2008-12-30 16:15:14
la source

il n'y a qu'une chose pourquoi préférer un DependencyObject - la reliure fonctionnera mieux. Il suffit d'essayer un exemple avec un ListBox et TextBox , peupler la liste avec les données de INotifyPropertyChanged propriété vs. DependencyProperty et éditer l'élément courant de TextBox ...

3
répondu ramos 2012-11-26 10:24:28
la source

si vous voulez exposer des propriétés à d'autres contrôles, vous devez utiliser des propriétés de dépendance... Mais bonne chance parce que ça prend du temps à comprendre...

1
répondu JWP 2011-02-04 00:05:21
la source