удобен своей возможностью информировать внешние объекты, когда его содержимое каким-то образом изменяется (как и можно было догадаться, работа с
ReadOnlyObservableCollection<T>
похожа, но по своей природе допускает только чтение).
Работа с классом ObservableCollection<T>
Создайте новый проект консольного приложения по имени
FunWithObservableCollections
и импортируйте в первоначальный файл кода C# пространство
имен
System.Collections.ObjectModel
. Во многих отношениях работа с
ObservableCollection<T>
идентична работе с
List<T>
, учитывая, что оба класса реализуют те же самые основные интерфейсы. Уникальным класс
ObservableCollection<T
> делает тот факт, что он поддерживает событие по имени
CollectionChanged
. Указанное событие будет инициироваться каждый раз, когда вставляется новый элемент, удаляется (или перемещается) существующий элемент либо модифицируется вся коллекция целиком.
Подобно любому другому событию событие
CollectionChanged
определено в терминах делегата, которым в данном случае является
NotifyCollectionChangedEventHandler
. Этот делегат может вызывать любой метод, который принимает
object
в первом параметре и
NotifyCollectionChangedEventArgs
— во втором. Рассмотрим следующий код, в котором наполняется наблюдаемая коллекция, содержащая объекты
Person
, и осуществляется привязка к событию
CollectionChanged
:
using System;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using FunWithObservableCollections;
// Сделать коллекцию наблюдаемой
// и добавить в нее несколько объектов Person.
ObservableCollection<Person> people = new ObservableCollection<Person>
{
new Person{ FirstName = "Peter", LastName = "Murphy", Age = 52 },
new Person{ FirstName = "Kevin", LastName = "Key", Age = 48 },
, которые выдают список элементов, имеющихся в коллекции перед генерацией события, и список новых элементов, вовлеченных в изменение. Тем не менее, такие списки будут исследоваться только в подходящих обстоятельствах. Вспомните, что событие
CollectionChanged
инициируется при добавлении, удалении, перемещении или сбросе элементов. Чтобы выяснить, какое из упомянутых действий запустило событие, можно использовать свойство
Action
объекта
NotifyCollectionChangedEventArgs
. Свойство
Action
допускается проверять на предмет равенства любому из членов перечисления
NotifyCollectionChangedAction
:
public enum NotifyCollectionChangedAction
{
Add = 0,
Remove = 1,
Replace = 2,
Move = 3,
Reset = 4,
}
Ниже
показана реализация обработчика событий
CollectionChanged
, который будет обходить старый и новый наборы, когда элемент вставляется или удаляется из имеющейся коллекции (обратите внимание на оператор
// Выяснить действие, которое привело к генерации события.
Console.WriteLine("Action for this event: {0}", e.Action);
// Было что-то удалено.
if (e.Action == NotifyCollectionChangedAction.Remove)
{
Console.WriteLine("Here are the OLD items:"); // старые элементы
foreach (Person p in e.OldItems)
{
Console.WriteLine(p.ToString);
}
Console.WriteLine;
}
// Было что-то добавлено.
if (e.Action == NotifyCollectionChangedAction.Add)
{
// Теперь вывести новые элементы, которые были вставлены.
Console.WriteLine("Here are the NEW items:"); // Новые элементы
foreach (Person p in e.NewItems)
{
Console.WriteLine(p.ToString);
}
}
}
Модифицируйте вызывающий код для добавления и удаления элемента:
// Добавить новый элемент.
people.Add(new Person("Fred", "Smith", 32));
// Удалить элемент.
people.RemoveAt(0);
В результате запуска программы вы получите вывод следующего вида:
Action for this event: Add
Here are the NEW items:
Name: Fred Smith, Age: 32
Action for this event: Remove
Here are the OLD items:
Name: Peter Murphy, Age: 52
На этом исследование различных пространств имен, связанных с коллекциями, завершено. В конце главы будет также объясняться, как и для чего строить собственные обобщенные методы и обобщенные типы.
Создание специальных обобщенных методов
Несмотря на то что большинство разработчиков обычно применяют обобщенные типы, имеющиеся в библиотеках базовых классов, существует также возможность построения собственных обобщенных методов и специальных обобщенных типов. Давайте посмотрим, как включать обобщения в свои проекты. Первым делом будет построен обобщенный метод обмена. Начните с создания нового проекта консольного приложения по имени