2010-01-08 5 views
2

Je suis nouveau à WPF et j'essaie de comprendre le cadre de WPF, ce qu'il fait et ce qu'il ne fait pas pour vous.Collections WPF et liaison de données

Pour clarifier cela, je voudrais savoir quelle est la différence entre ceci:

public List<MyCustomObject> MyCustomObjects 
{ 
    get { return (List<MyCustomObject>)GetValue(MyCustomObjectsProperty); } 
    set { SetValue(MyCustomObjectsProperty, value); } 
} 

public static readonly DependencyProperty MyCustomObjectsProperty = 
    DependencyProperty.Register("MyCustomObjects", typeof(List<MyCustomObject>), 
    typeof(Main), new UIPropertyMetadata(new List<MyCustomObject>())); 



et ceci:

public ObservableCollection<MyCustomObject> MyCustomObjects { get; set; } 

public Main() 
{ 
    MyCustomObjects = new ObservableCollection<<MyCustomObject>(); 
} 
+0

Merci à tous pour les réponses. Cwap a semblé le clarifier le plus pour moi, alors je suis allé avec le sien, mais j'ai tout chamboulé. Merci encore! – Vaccano

Répondre

1

1:

Vous utilisez une propriété de dépendance à « dire » le cadre quand cette propriété est modifiée.Cela aura les conséquences suivantes pour votre reliure:

MyCustomObjects.Add(new MyCustomObject()); //Wont update the view through databinding 
MyCustomObjects = new List<MyCustomObject>(); //Will update the view through databinding 

Vous pouvez gagner la même fonctionnalité de liaison de données en mettant en œuvre INotifyPropertyChanged sur lequel expose toujours classe la propriété, mais les propriétés de dépendance une capable de bien plus qu'une simple notification des changements. Ce sont plutôt des fonctionnalités avancées cependant, que vous n'êtes pas susceptible de rencontrer dans votre application joe moyenne :)

2:

Vous utilisez une collection observable, qui met en œuvre INotifyCollectionChanged pour vous, de dire la liaison de données chaque fois que le contenu de la collection a changé. Cela aura des conséquences opposées que # 1:

MyCustomObjects.Add(new MyCustomObject()); //Will update the view through databinding 
MyCustomObjects = new ObservableCollection<MyCustomObject>(); //Won't update the view through databinding 
+0

Si je fais un ObserverableCollection qui est un DependencyProperty, aurai-je les deux? est-ce une bonne idée? – Vaccano

+1

Vous aurez les deux, oui. Si c'est une bonne idée dépend de vos besoins, mais je l'ai souvent implémenté (bien que je préfère utiliser INotifyPropertyChanged, car c'est plus simple). – cwap

+0

Depuis l'OP a approuvé la réponse, je prends la liberté de l'éditer pour corriger certaines inexactitudes (INotifyPropertyChanged -> INotifyCollectionChanged, etc.) –

2

Dans le premier cas, vous configurez une propriété Dependency contenant une instance List<T>. Dans la seconde, vous créez une propriété CLR normale, mais en la configurant comme ObservableCollection<T>.

Pour la liaison de données WPF, il existe quelques différences ici.

En règle générale, vous voulez toutes vos propriétés dans le DataContext (qui est l'objet par défaut que les choses "bind") à implémenter INotifyPropertyChanged ou être une propriété de dépendance. Cela permet au cadre de liaison de savoir quand des modifications sont apportées à cet objet. Normalement, cependant, vous n'utiliseriez une propriété de dépendance que si vous travaillez avec un contrôle personnalisé - c'est généralement une meilleure idée d'avoir votre objet auquel vos données sont liées dans une classe distincte, assignée au DataContext. (Pour plus de détails ici, voir Josh Smith on MVVM ou my recent detailed post on MVVM ...)

Cependant, avec une collection, vous aussi généralement que le système de liaison de savoir quand les éléments dans le changement de collection (ex: un élément est ajouté). ObservableCollection<T> gère cela en implémentant INotifyCollectionChanged. En utilisant la seconde approche (en utilisant un ObservableCollection<T>), votre interface utilisateur peut savoir quand des éléments ont été ajoutés ou retirés de la collection - pas seulement quand une nouvelle collection est assignée. Cela permet aux choses de fonctionner automatiquement, comme un ListBox ajoutant des éléments quand un nouvel élément est ajouté à votre collection.

4

Ok, il faut mettre de l'ordre dans les choses, il y a quelques concepts mélangés ici. Tout d'abord, vous demandez quelle est la différence entre une propriété sauvegardée par le champ et une propriété de dépendance. Google serait votre meilleur ami, mais je recommande ce billet de blog par l'avant-garde Josh Smith WPF: Overview of dependency properties in WPF

En bref: propriétés de dépendance soutiennent la richesse qui est WPF: Styling, animation, reliure, méta-données, et plus encore. Ensuite, vous demandez quelle est la différence entre un List et un ObservableCollection. Eh bien, le dernier fournit des notifications de changement (dans les formes d'événements) sur tout changement à la collection (ajout, suppression, changement d'ordre, compensation, etc.), et le premier ne le fait pas. Vous pouvez en savoir plus à ce sujet ici: The ObservableCollection Class

En bref:ObservableCollection fournit des notifications de modification qui sont nécessaires pour l'interface utilisateur afin de refléter automatiquement les modifications du modèle de vue.

4

En plus de Aviad et les réponses de Reed, je voudrais signaler un bogue sérieux dans votre premier exemple de code:

public static readonly DependencyProperty MyCustomObjectsProperty = 
    DependencyProperty.Register("MyCustomObjects", typeof(List<MyCustomObject>), 
    typeof(Main), new UIPropertyMetadata(new List<MyCustomObject>())); 

Le new List<MyCustomObject>() utilisés comme la valeur par défaut sera créé une seule fois, donc par défaut toutes les instances de votre type partageront la même instance List<MyCustomObject>, ce qui n'est probablement pas ce que vous voulez ... La seule valeur par défaut est ici null

+0

Si vrai, et une erreur de débutant commun. Attention à cela! –

+0

Hmmm, je crains de ne pas avoir ça ... Je veux une liste MyCustomObjects. Je ne fais pas plus d'une instance de la variable MyCustomObjects (vous faites référence à "toutes les instances" mais je n'aurais pas une seule instance comme déclarée dans ma propriété). J'espère que vous répondez parce que je peux dire que c'est important, mais je ne comprends tout simplement pas. – Vaccano

+0

La même instance de la liste sera partagée par tous vos objets de type 'Main' (sauf indication contraire explicite). –