MySQL Java JavaScript PHP Python HTML-CSS C-sharp

Clasa ObservableCollection

Pe lângă clasele de colecții standard, cum ar fi listele, cozile, dicționarele și stivele, .NET oferă și o clasă specială numită ObservableCollection<T>. Spre deosebire de colecțiile discutate anterior, această clasă este definită în spațiul de nume System.Collections.ObjectModel.

Funcționalitatea colecției ObservableCollection este similară cu cea a listei List, cu excepția faptului că permite notificarea obiectelor externe atunci când colecția este modificată.

Crearea și inițializarea ObservableCollection

Pentru a crea un obiect, clasa ObservableCollection oferă mai mulți constructori. În primul rând, putem crea o colecție goală:

using System.Collections.ObjectModel;

ObservableCollection<string> people = new ObservableCollection<string>();

În acest caz, colecția people este tipizată cu tipul string, deci poate stoca doar șiruri de caractere.

O altă versiune a constructorului permite transmiterea în ObservableCollection a obiectelor dintr-o altă colecție sau array:

var people = new ObservableCollection<string>( new string[] {"Tom", "Bob", "Sam"});

Pentru inițializare, putem transmite valori printr-un inițializator între acolade:

var people = new ObservableCollection<string>
{
   "Tom", "Bob", "Sam"
};

De asemenea, putem combina cele două metode anterioare:

var people = new ObservableCollection<string>( new string[] {"Mike", "Alice", "Kate" })
{
   "Tom", "Bob", "Sam"
};

Accesarea elementelor colecției

Pentru a accesa elementele ObservableCollection, putem folosi indecși similar cu array-urile sau listele List:

var people = new ObservableCollection<string>
{
   "Tom", "Bob", "Sam"
};

// obținem primul element
Console.WriteLine(people[0]);   // Tom
// modificăm primul element
people[0] = "Tomas";
Console.WriteLine(people[0]);   // Tomas

Parcurgerea colecției

Pentru a parcurge colecția, putem folosi cicluri standard:

using System.Collections.ObjectModel;

var people = new ObservableCollection<string>
{
   "Tom", "Bob", "Sam"
};

foreach(var person in people)
{
   Console.WriteLine(person);
}

for (int i =0; i < people.Count; i++)
{
   Console.WriteLine(people[i]);
}

Cu ajutorul proprietății Count, putem obține numărul de elemente din colecție.

Metodele ObservableCollection

Dintre metodele clasei ObservableCollection, menționăm următoarele:

  • void Add(T item): adaugă un nou element în colecție
  • void CopyTo(T[] array, int index): copiază în array elementele din colecție începând de la indexul specificat
  • bool Contains(T item): returnează true dacă elementul item există în colecție
  • void Clear(): șterge toate elementele din colecție
  • int IndexOf(T item): returnează indexul primei apariții a elementului în colecție
  • void Insert(int index, T item): inserează elementul item în colecție la indexulspecificat. Dacă nu există un astfel de index în colecție, se generează o excepție
  • bool Remove(T item): șterge elementul item din colecție și returnează true dacă ștergerea a avut succes. Dacă în colecție există mai multe elemente identice, se șterge doar primul dintre ele
  • void RemoveAt(int index): șterge elementul de la indexul specificat. Dacă nu există un astfel de index în colecție, se generează o excepție
  • void Move(int oldIndex, int newIndex): mută elementul de la indexul oldIndex la poziția specificată de newIndex

Aplicarea metodelor:

using System.Collections.ObjectModel;

var people = new ObservableCollection<string>();

// adăugăm un element
people.Add("Bob");
// inserăm un element la indexul 0
people.Insert(0, "Tom");

// verificarea existenței elementului
bool bobExists = people.Contains("Bob");     // true
Console.WriteLine($"Bob exists: {bobExists}");
bool mikeExists = people.Contains("Mike");   // false
Console.WriteLine($"Mike exists: {mikeExists}");

// ștergerea unui element
people.Remove("Tom");
// ștergerea unui element de la indexul 0
people.RemoveAt(0);

Notificarea modificării colecției

Clasa ObservableCollection definește evenimentul CollectionChanged, la care ne putem abona pentru a gestiona orice modificări ale colecției. Acest eveniment este reprezentat de delegatul NotifyCollectionChangedEventHandler:

void NotifyCollectionChangedEventHandler(object? sender, NotifyCollectionChangedEventArgs e);

Al doilea parametru al delegatului - obiectul NotifyCollectionChangedEventArgs - stochează toate informațiile despre eveniment. În special, proprietatea sa Action permite aflarea naturii modificărilor. Aceasta stochează una dintre valorile din enumerarea NotifyCollectionChangedAction:

  • NotifyCollectionChangedAction.Add: adăugare
  • NotifyCollectionChangedAction.Remove: ștergere
  • NotifyCollectionChangedAction.Replace: înlocuire
  • NotifyCollectionChangedAction.Move: mutarea obiectului în cadrul colecției la o nouă poziție
  • NotifyCollectionChangedAction.Reset: resetarea conținutului colecției (de exemplu, la ștergerea colecției cu metoda Clear())

În plus, proprietățile NewItems și OldItems permit obținerea respectiv a obiectelor adăugate și șterse. Astfel, avem control deplin asupra gestionării adăugării, ștergerii și înlocuirii obiectelor din colecție.

Să presupunem că avem următoarea clasă Person, care reprezintă un utilizator:

class Person
{
   public string Name { get; }
   public Person(string name) => Name = name;
}

Pentru a gestiona colecția de obiecte Person, definim următorul program:

using System.Collections.ObjectModel;
using System.Collections.Specialized;

var people = new ObservableCollection<Person>()
{
   new Person("Tom"),
   new Person("Sam")
};
// ne abonăm la evenimentul de modificare a colecției
people.CollectionChanged += People_CollectionChanged;

people.Add(new Person("Bob"));  // adăugăm un nou element

people.RemoveAt(1);                 // ștergem un element
people[0] = new Person("Eugene");   // înlocuim un element

Console.WriteLine("\nLista utilizatorilor:");
foreach (var person in people)
{
   Console.WriteLine(person.Name);
}

// handler pentru modificarea colecției
void People_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
{
   switch (e.Action)
   {
       case NotifyCollectionChangedAction.Add: // dacă este adăugare
           if(e.NewItems?[0] is Person newPerson)
               Console.WriteLine($"Adăugat obiect nou: {newPerson.Name}");
           break;
       case NotifyCollectionChangedAction.Remove: // dacă este ștergere
           if (e.OldItems?[0] is Person oldPerson)
               Console.WriteLine($"Șters obiect: {oldPerson.Name}");
           break;
       case NotifyCollectionChangedAction.Replace: // dacă este înlocuire
           if ((e.NewItems?[0] is Person replacingPerson)  &&
               (e.OldItems?[0] is Person replacedPerson))
               Console.WriteLine($"Obiectul {replacedPerson.Name} a fost înlocuit cu obiectul {replacingPerson.Name}");
           break;
   }
}

Aici, metoda People_CollectionChanged acționează ca un handler pentru modificările colecției, iar cu ajutorul parametrului NotifyCollectionChangedEventArgs obținem informații despre modificare.

Rezultatul în consolă al programului:


Adăugat obiect nou: Bob
Șters obiect: Sam
Obiectul Tom a fost înlocuit cu obiectul Eugene

Lista utilizatorilor:
Eugene
Bob
← Lecția anterioară Lecția următoare →