Содержание
Ещё один интересный и полезный в работе класс коллекций, предоставляемый платформой .NET — класс ObservableCollection располагается в пространстве имен System.Collections.ObjectModel. В целом, этот класс по своим свойствам и методам соответствует обычному списку List за тем лишь исключением, что ObservableCollection позволяет отслеживать изменения, происходящие со списком объектов и информировать другие объекты об этих изменениях.
Информация по работе с универсальными списками рассматривалась в нескольких статьях блога, а именно:
Поэтому нет необходимости в этой статье возвращаться к рассмотрению свойств и методов у класса ObservableCollection. Рассмотрим только те вопросы, которые касаются непосредственно рассматриваемого класса, то есть — работу с событиями класса ObservableCollection.
Уведомления об изменении коллекции
У класса ObservableCollection определено событие CollectionChanged, подписавшись на которое становится возможным получение уведомления об изменениях коллекции. Это событие представляет собой делегат NotifyCollectionChangedEventHandler:
public delegate void NotifyCollectionChangedEventHandler(object? sender, NotifyCollectionChangedEventArgs e);
Во втором параметре делегата — NotifyCollectionChangedEventArgs хранится вся информация об изменении коллекции. NotifyCollectionChangedEventArgs содержит в том числе следующие полезные свойства:
Action |
Действие, которое произошло в коллекции. Может принимать следующие значения:
|
New |
Получает список новых элементов, связанных с изменением. |
New |
Возвращает индекс, в котором произошло изменение. |
Old |
Получает список элементов, затрагиваемых действием Replace, Remove или Move. |
Old |
Возвращает индекс, по которому произошло действие Move, Remove или Replace. |
Рассмотрим следующие пример, демонстрирующий получение изменений в коллекции:
using System;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
namespace QueueExample
{
internal class Program
{
static void Main(string[] args)
{
ObservableCollection<string> fruits = new ObservableCollection<string>();
fruits.CollectionChanged += ChangedHandler;
fruits.Add("Яблоко");
fruits.Add("Груша");
fruits.Add("Апельсин");
fruits.Add("Банан");
fruits[0] = "Дыня";
fruits.Remove("Банан");
fruits.Move(0, 1);
fruits.Clear();
}
public static void ChangedHandler(object? sender, NotifyCollectionChangedEventArgs e)
{
switch (e.Action)
{
case NotifyCollectionChangedAction.Add:
{
Console.WriteLine($"Добавлен новый элемент {e.NewItems[0]}");
break;
}
case NotifyCollectionChangedAction.Remove:
{
Console.WriteLine($"Удален элемент {e.OldItems[0]}");
break;
}
case NotifyCollectionChangedAction.Replace:
{
Console.WriteLine($"Элемент {e.OldItems[0]} заменен на {e.NewItems[0]}");
break;
}
case NotifyCollectionChangedAction.Move:
{
Console.WriteLine($"Перемещен элемент {e.OldItems[0]} из позиции {e.OldStartingIndex} в позицию {e.NewStartingIndex}");
break;
}
case NotifyCollectionChangedAction.Reset:
{
Console.WriteLine("Коллекция сброшена");
break;
}
}
}
}
}
Первое, что мы делаем — это создаем новую коллекцию:
ObservableCollection<string> fruits = new ObservableCollection<string>();
Далее, чтобы получать уведомления об изменении в коллекции, мы создали метод ChangedHandler и подписались на событие CollectionChanged у коллекции:
fruits.CollectionChanged += ChangedHandler;
После этого, мы начинаем работу с элементами коллекции — добавляем новые элементы, перемещаем элементы внутри коллекции, удаляем элементы и, в завершении, полностью очищаем коллекцию, вызвав метод Clear(). Все эти действия обрабатываются в методе ChangedHandler и выводятся в консоль. Результат работы приложения представлен ниже:
Добавлен новый элемент Груша
Добавлен новый элемент Апельсин
Добавлен новый элемент Банан
Элемент Яблоко заменен на Дыня
Удален элемент Банан
Перемещен элемент Дыня из позиции 0 в позицию 1
Коллекция сброшена
Отметим, что в методе ChangedHandler мы получаем информацию об элементах коллекции следующим образом: e.OldItems[0] или e.NewItems[0] . Так как мы работали с элементами коллекции по одному, то такая конструкция (для примера) допустима — мы просто запрашивали первый (и единственный) элемент из списка OldItems или NewItems.
Итого
ObservableCollection — это класс коллекции, которая позволяет подписаться на уведомления об изменениях. Используя событие CollectionChanged, мы можем получать уведомления о добавлении, удалении, перемещении элементов в коллекции, а также об очистке коллекции от всего содержимого, например, при вызове метода Clear().