À quoi sert ObservableCollection dans .net?


227

À quoi sert ObservableCollection dans .net?


1
@ alpha-mouse: Pouvez-vous donner un peu plus d'informations sur le problème que vous essayez de résoudre? Cela aidera les gens à vous donner des exemples pertinents.
Jazza

@Jazza: Je viens de changer les balises de la question =) Je ne suis pas la question de santosh
alpha-mouse

3
@TheMuffinMan true, pourtant je préfère la façon dont les choses sont expliquées sur stackoverflow par rapport à la manière trop rigide et formelle de MSDN d'expliquer leurs propres créations.
Sizons

Réponses:


224

ObservableCollection est une collection qui permet au code en dehors de la collection de savoir quand des modifications de la collection (ajouter, déplacer, supprimer) se produisent. Il est largement utilisé dans WPF et Silverlight mais son utilisation ne s'y limite pas. Le code peut ajouter des gestionnaires d'événements pour voir quand la collection a changé, puis réagir via le gestionnaire d'événements pour effectuer un traitement supplémentaire. Cela peut changer une interface utilisateur ou effectuer une autre opération.

Le code ci-dessous ne fait rien mais montre comment attacher un gestionnaire dans une classe, puis utiliser les arguments d'événement pour réagir d'une manière ou d'une autre aux modifications. WPF a déjà de nombreuses opérations comme l'actualisation de l'interface utilisateur intégrée afin que vous les obteniez gratuitement lorsque vous utilisez ObservableCollections

class Handler
{
    private ObservableCollection<string> collection;

    public Handler()
    {
        collection = new ObservableCollection<string>();
        collection.CollectionChanged += HandleChange;
    }

    private void HandleChange(object sender, NotifyCollectionChangedEventArgs e)
    {
        foreach (var x in e.NewItems)
        {
            // do something
        }

        foreach (var y in e.OldItems)
        {
            //do something
        }
        if (e.Action == NotifyCollectionChangedAction.Move)
        {
            //do something
        }
    }
}

21
e.NewItems& e.OldsItemspeut être nul en fonction de l'action. Ça peut jeter NullReferenceException.
dovid

7
sidenote: lorsque Action est Move, l'élément déplacé apparaîtra à la fois dans NewItems et
OldItems

Merci pour cela:> WPF a déjà de nombreuses opérations comme l'actualisation de l'interface utilisateur intégrée, vous les obtenez donc gratuitement lorsque vous utilisez ObservableCollections
SlowLearner

157

Un ObservableCollectionfonctionne essentiellement comme une collection régulière, sauf qu'il implémente les interfaces:

En tant que tel, il est très utile lorsque vous souhaitez savoir quand la collection a changé. Un événement est déclenché qui indiquera à l'utilisateur quelles entrées ont été ajoutées / supprimées ou déplacées.

Plus important encore, ils sont très utiles lors de l'utilisation de la liaison de données sur un formulaire.


54

À partir de Pro C # 5.0 et du .NET 4.5 Framework

La ObservableCollection<T>classe est très utile en ce qu'elle a la capacité d'informer les objets externes lorsque son contenu a changé d'une manière ou d'une autre (comme vous pouvez le deviner, travailler avec ReadOnlyObservableCollection<T>est très similaire, mais en lecture seule dans la nature). À bien des égards, travailler avec ObservableCollection<T>est identique à travailler avec List<T>, étant donné que ces deux classes implémentent les mêmes interfaces principales. Ce qui rend la ObservableCollection<T>classe unique, c'est que cette classe prend en charge un événement nommé CollectionChanged. Cet événement se déclenche chaque fois qu'un nouvel élément est inséré, un élément actuel est supprimé (ou déplacé), ou si la collection entière est modifiée. Comme tout événement, CollectionChanged est défini en termes de délégué, ce qui est le cas dans ce cas NotifyCollectionChangedEventHandler. Ce délégué peut appeler n'importe quelle méthode qui prend un objet comme premier paramètre et unNotifyCollectionChangedEventArgscomme deuxième. Considérez la méthode Main () suivante, qui remplit une collection observable contenant des objets Person et relie l' CollectionChangedévénement:

class Program
{
   static void Main(string[] args)
   {
     // Make a collection to observe and add a few Person objects.
     ObservableCollection<Person> people = new ObservableCollection<Person>()
     {
        new Person{ FirstName = "Peter", LastName = "Murphy", Age = 52 },
        new Person{ FirstName = "Kevin", LastName = "Key", Age = 48 },
     };
     // Wire up the CollectionChanged event.
     people.CollectionChanged += people_CollectionChanged;
     // Now add a new item.
     people.Add(new Person("Fred", "Smith", 32));

     // Remove an item.
     people.RemoveAt(0);

     Console.ReadLine();
   }
   static void people_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
   {
       // What was the action that caused the event?
        Console.WriteLine("Action for this event: {0}", e.Action);

        // They removed something. 
        if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
        {
            Console.WriteLine("Here are the OLD items:");
            foreach (Person p in e.OldItems)
            {
                Console.WriteLine(p.ToString());
            }
            Console.WriteLine();
        }

        // They added something. 
        if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
        {
            // Now show the NEW items that were inserted.
            Console.WriteLine("Here are the NEW items:");
            foreach (Person p in e.NewItems)
            {
                Console.WriteLine(p.ToString());
            }
        }
   }
}

Le NotifyCollectionChangedEventArgsparamètre entrant définit deux propriétés importantes OldItemset NewItemsqui vous donneront une liste des éléments qui étaient actuellement dans la collection avant le déclenchement de l'événement et les nouveaux éléments qui ont été impliqués dans la modification. Cependant, vous souhaiterez examiner ces listes uniquement dans les circonstances appropriées. Rappelez-vous que l'événement CollectionChanged peut se déclencher lorsque des éléments sont ajoutés, supprimés, déplacés ou réinitialisés. Pour découvrir laquelle de ces actions a déclenché l'événement, vous pouvez utiliser la propriété Action de NotifyCollectionChangedEventArgs. La propriété Action peut être testée par rapport à l'un des membres suivants de l' NotifyCollectionChangedActionénumération:

public enum NotifyCollectionChangedAction
{
Add = 0,
Remove = 1,
Replace = 2,
Move = 3,
Reset = 4,
}

Membres de System.Collections.ObjectModel


1
l'événement people_CollectionChanged se déclenchera-t-il si je change le nom d'une personne dans la collection (sans modifier la collection elle-même?)
BKSpurgeon

25

Explication sans code

Pour ceux qui veulent une réponse sans aucun code (boom-tish), je lèverai la main:

Collections normales - Aucune notification

De temps en temps, je vais à New York et ma femme me demande d'acheter des trucs. Je prends donc une liste de courses avec moi. La liste contient beaucoup de choses comme:

  1. Sac à main Louis Vuitton (5000 $)
  2. Parfum Majesté Impériale de Clive Christian (215 000 $)
  3. Lunettes de soleil Gucci (2000 $)

hahaha eh bien je n'achète pas ces trucs. Alors je les raye et les supprime de la liste et j'ajoute à la place:

  1. 12 douzaines de balles de golf Titleist.
  2. Boule de bowling de 12 lb.

Je rentre donc généralement sans les marchandises et elle n'est jamais contente. Le fait est qu'elle ne sait pas ce que je retire de la liste et ce que j'y ajoute; elle ne reçoit aucune notification.

The ObservableCollection - notifications lorsque des modifications sont apportées

Maintenant, chaque fois que je retire quelque chose de la liste: elle reçoit une notification sur son téléphone (sms / email, etc.)!

La collection observable fonctionne de la même manière. Si vous y ajoutez ou en supprimez quelque chose: quelqu'un en est informé. Et quand ils sont informés, eh bien ils vous appellent et vous en aurez plein l'oreille. Bien sûr, les conséquences sont personnalisables via le gestionnaire d'événements.

Cela résume tout!


7

L'une des plus grandes utilisations est que vous pouvez lier des composants d'interface utilisateur à un, et ils répondront de manière appropriée si le contenu de la collection change. Par exemple, si vous liez une ItemSource d'un ListView à un, le contenu du ListView sera automatiquement mis à jour si vous modifiez la collection.

EDIT: Voici un exemple de code de MSDN: http://msdn.microsoft.com/en-us/library/ms748365.aspx

En C #, accrocher la ListBox à la collection peut être aussi simple que

listBox.ItemsSource = NameListData;

cependant, si vous n'avez pas connecté la liste en tant que ressource statique et défini NameItemTemplate, vous souhaiterez peut-être remplacer ToString () de PersonName. Par exemple:

public override ToString()
{
    return string.Format("{0} {1}", this.FirstName, this.LastName);
}

6

c'est une collection qui est utilisée pour notifier principalement l'interface utilisateur de changer dans la collection, elle prend en charge la notification automatique.

Principalement utilisé dans WPF,

Où supposons que vous ayez une interface utilisateur avec une zone de liste et un bouton d'ajout et que lorsque vous cliquez sur le bouton, un objet de type suppose que personne sera ajouté à la collection obseravable et que vous liez cette collection à ItemSource de Listbox, donc dès que vous avez ajouté un nouvel élément dans la collection, Listbox se mettra à jour automatiquement et y ajoutera un élément.


vraiment ça arrive ?? : O
Kings

5
class FooObservableCollection : ObservableCollection<Foo>
{
    protected override void InsertItem(int index, Foo item)
    {
        base.Add(index, Foo);

        if (this.CollectionChanged != null)
            this.CollectionChanged(this, new NotifyCollectionChangedEventArgs (NotifyCollectionChangedAction.Add, item, index);
    }
}

var collection = new FooObservableCollection();
collection.CollectionChanged += CollectionChanged;

collection.Add(new Foo());

void CollectionChanged (object sender, NotifyCollectionChangedEventArgs e)
{
    Foo newItem = e.NewItems.OfType<Foo>().First();
}

pouvez-vous expliquer pourquoi FooObservableCollection a implémenté la collecte? Et pourquoi avez-vous outrepassé InsertItem?
Arie

@Arie: honnêtement, 8 ans plus tard, je ne me souviens pas, donc aucune idée. D'après ce que je vois dans les documents , rien de tout cela n'est nécessaire, tout devrait sortir de la boîte.
abatishchev
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.