Содержание
Ещё один интересный и полезный в работе класс коллекций, предоставляемый платформой .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()
.