Was ist die Verwendung von ObservableCollection in .net?

227

Was ist die Verwendung von ObservableCollection in .net?

Santosh Singh
quelle
1
@ alpha-mouse: Können Sie etwas mehr Informationen über das Problem geben, das Sie lösen möchten? Dies wird Menschen helfen, Ihnen relevante Beispiele zu geben.
Jazza
@ Jazzza: Ich habe gerade Tags der Frage geändert =) Ich bin nicht Santoshs Frage
Alpha-Maus
3
@TheMuffinMan stimmt, aber ich bevorzuge die Art und Weise, wie Dinge im Stackoverflow erklärt werden, im Vergleich zu MSDNs, die zu starr sind, um ihre eigenen Kreationen formal zu erklären.
Sizons

Antworten:

224

ObservableCollection ist eine Sammlung, mit der Code außerhalb der Sammlung erkennen kann, wann Änderungen an der Sammlung (Hinzufügen, Verschieben, Entfernen) auftreten. Es wird häufig in WPF und Silverlight verwendet, ist jedoch nicht auf diese beschränkt. Code kann Ereignishandler hinzufügen, um zu sehen, wann sich die Sammlung geändert hat, und dann über den Ereignishandler reagieren, um eine zusätzliche Verarbeitung durchzuführen. Dies kann eine Benutzeroberfläche ändern oder eine andere Operation ausführen.

Der folgende Code bewirkt eigentlich nichts anderes, zeigt jedoch, wie Sie einen Handler in einer Klasse anhängen und dann die Ereignisargumente verwenden, um auf die Änderungen zu reagieren. In WPF sind bereits viele Vorgänge wie das Aktualisieren der Benutzeroberfläche integriert, sodass Sie diese bei Verwendung von ObservableCollections kostenlos erhalten

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
        }
    }
}
Craig Suchanec
quelle
21
e.NewItems& e.OldsItemskann je nach Aktion null sein. Es kann werfen NullReferenceException.
Dovid
7
Nebenbemerkung: Wenn Aktion Verschieben ist, wird das verschobene Element sowohl in NewItems als auch in OldItems angezeigt
bohdan_trotsenko
Vielen Dank dafür:> In WPF sind bereits viele Vorgänge wie das Aktualisieren der Benutzeroberfläche integriert, sodass Sie diese kostenlos erhalten, wenn Sie ObservableCollections
SlowLearner am
157

Ein ObservableCollectionfunktioniert im Wesentlichen wie eine reguläre Sammlung, außer dass es die Schnittstellen implementiert:

Daher ist es sehr nützlich, wenn Sie wissen möchten, wann sich die Sammlung geändert hat. Es wird ein Ereignis ausgelöst, das dem Benutzer mitteilt, welche Einträge hinzugefügt / entfernt oder verschoben wurden.

Noch wichtiger ist, dass sie sehr nützlich sind, wenn Sie die Datenbindung in einem Formular verwenden.

Liz
quelle
54

Ab Pro C # 5.0 und .NET 4.5 Framework

Die ObservableCollection<T>Klasse ist insofern sehr nützlich, als sie externe Objekte informieren kann, wenn sich ihr Inhalt auf irgendeine Weise geändert hat (wie Sie sich vorstellen können, ist die Arbeit mit ReadOnlyObservableCollection<T>sehr ähnlich, aber schreibgeschützt). In vielerlei Hinsicht ist das Arbeiten mit dem ObservableCollection<T>identisch mit dem Arbeiten mit List<T>, da beide Klassen dieselben Kernschnittstellen implementieren. Was die ObservableCollection<T>Klasse einzigartig macht, ist, dass diese Klasse ein Ereignis mit dem Namen unterstützt CollectionChanged. Dieses Ereignis wird ausgelöst, wenn ein neues Element eingefügt, ein aktuelles Element entfernt (oder verschoben) oder wenn die gesamte Sammlung geändert wird. Wie jedes Ereignis wird CollectionChanged als Delegat definiert, in diesem Fall NotifyCollectionChangedEventHandler. Dieser Delegat kann jede Methode aufrufen, die ein Objekt als ersten Parameter verwendet, und aNotifyCollectionChangedEventArgsals der zweite. Betrachten Sie die folgende Main () -Methode, die eine beobachtbare Sammlung mit Personenobjekten auffüllt und das CollectionChangedEreignis verkabelt:

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());
            }
        }
   }
}

Der eingehende NotifyCollectionChangedEventArgsParameter definiert zwei wichtige Eigenschaften: OldItemsund NewItemsgibt Ihnen eine Liste der Elemente, die sich vor dem Auslösen des Ereignisses derzeit in der Sammlung befanden, sowie der neuen Elemente, die an der Änderung beteiligt waren. Sie sollten diese Listen jedoch nur unter den richtigen Umständen überprüfen. Denken Sie daran, dass das CollectionChanged-Ereignis ausgelöst werden kann, wenn Elemente hinzugefügt, entfernt, verschoben oder zurückgesetzt werden. Um herauszufinden, welche dieser Aktionen das Ereignis ausgelöst hat, können Sie die Action-Eigenschaft von NotifyCollectionChangedEventArgs verwenden. Die Action-Eigenschaft kann gegen eines der folgenden Mitglieder der NotifyCollectionChangedActionAufzählung getestet werden:

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

Mitglieder von System.Collections.ObjectModel

Sagte Roohullah Allem
quelle
1
Wird das Ereignis people_CollectionChanged ausgelöst, wenn ich den Namen einer Person in der Sammlung
ändere
25

Erklärung ohne Code

Für diejenigen, die eine Antwort ohne Code wollen (Boom-Tish), werde ich meine Hand erheben:

Normale Sammlungen - Keine Benachrichtigungen

Hin und wieder gehe ich nach NYC und meine Frau bittet mich, Sachen zu kaufen. Also nehme ich eine Einkaufsliste mit. Die Liste enthält viele Dinge wie:

  1. Louis Vuitton Handtasche ($ 5000)
  2. Parfüm der kaiserlichen Majestät von Clive Christian ($ 215.000)
  3. Gucci Sonnenbrille ($ 2000)

hahaha gut, ich kaufe das Zeug nicht. Also streiche ich sie ab und entferne sie von der Liste und füge stattdessen hinzu:

  1. 12 Dutzend Titleist Golfbälle.
  2. 12 lb Bowlingkugel.

Also komme ich normalerweise ohne die Ware nach Hause und sie ist nie zufrieden. Die Sache ist, dass sie nicht weiß, was ich von der Liste streichen und was ich dazu hinzufüge; Sie erhält keine Benachrichtigungen.

Die ObservableCollection - Benachrichtigungen bei vorgenommenen Änderungen

Wenn ich jetzt etwas von der Liste entferne: Sie erhält eine Benachrichtigung auf ihrem Telefon (z. B. SMS / E-Mail usw.)!

Die beobachtbare Sammlung funktioniert genauso. Wenn Sie etwas hinzufügen oder entfernen, wird jemand benachrichtigt. Und wenn sie benachrichtigt werden, rufen sie dich an und du bekommst ein Ohr voll. Natürlich können die Konsequenzen über den Event-Handler angepasst werden.

Das fasst alles zusammen!

BKSpurgeon
quelle
7

Eine der größten Verwendungsmöglichkeiten besteht darin, dass Sie UI-Komponenten an eine binden können. Diese reagieren angemessen, wenn sich der Inhalt der Sammlung ändert. Wenn Sie beispielsweise die ItemsSource einer ListView an eine binden, wird der Inhalt der ListView automatisch aktualisiert, wenn Sie die Sammlung ändern.

BEARBEITEN: Hier ist ein Beispielcode von MSDN: http://msdn.microsoft.com/en-us/library/ms748365.aspx

In C # kann das Verknüpfen der ListBox mit der Sammlung so einfach sein wie

listBox.ItemsSource = NameListData;

Wenn Sie die Liste jedoch nicht als statische Ressource verknüpft und NameItemTemplate definiert haben, möchten Sie möglicherweise ToString () von PersonName überschreiben. Beispielsweise:

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

Es handelt sich um eine Sammlung, die verwendet wird, um hauptsächlich die Benutzeroberfläche über Änderungen in der Sammlung zu benachrichtigen. Sie unterstützt die automatische Benachrichtigung.

Hauptsächlich in WPF verwendet,

Angenommen, Sie haben eine Benutzeroberfläche mit einem Listenfeld und einer Schaltfläche zum Hinzufügen. Wenn Sie auf die Schaltfläche klicken, wird der beobachtbaren Sammlung ein Objekt vom Typ "Angenommene Person" hinzugefügt, und Sie binden diese Sammlung an die ItemSource der Listbox, sobald Sie eine hinzugefügt haben Als neues Element in der Sammlung aktualisiert sich Listbox selbst und fügt ein weiteres Element hinzu.

TalentTuner
quelle
passiert das wirklich ?? : 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();
}
abatishchev
quelle
Können Sie erklären, warum FooObservableCollection die Sammlung implementiert hat? Und warum haben Sie InsertItem übersteuert?
Arie
@Arie: Ehrlich gesagt, 8 Jahre später erinnere ich mich nicht, also keine Ahnung. Nach dem, was ich in den Dokumenten sehe , ist dies alles nicht erforderlich, alles sollte sofort einsatzbereit sein.
Abatishchev