Лабораторная работа 4. Варианты второго уровня Делегаты. События Информация для всех вариантов В лабораторной работе требуется определить класс, содержащий типизированную коллекцию, который с помощью событий извещает об изменениях в коллекции и в данных ее элементов. Коллекция состоит из объектов ссылочных типов. Набор ссылок, образующих коллекцию, изменяется при удалении/добавлении элементов или при изменении одной из входящих в коллекцию ссылок, например, когда одной из ссылок присваивается новое значение. Класс, содержащий коллекцию, сообщает об этих изменениях в коллекции с помощью событий, для которых определяется пользовательский делегат. Данные элементов, входящих в коллекцию, изменяются при вызове метода get в свойствах, определенных в элементах коллекции. При этом значение самой ссылки, которая входит в коллекцию, не изменяется.
Элементы сообщают об изменениях в своих данных с помощью события PropertyChange интерфейса System.ComponentModel.INotifyPropertyChanged. Делегат, отвечающий этому событию, delegate void PropertyChangedEventHandler (Object sender,PropertyChangedEventArgs e); определен в базовой библиотеке. В классе PropertyChangedEventArgs есть конструктор с единственным параметром типа string, через который обработчикам события обычно передается имя свойства, которое является источником изменений данных объекта. Класс, содержащий коллекцию, должен подписаться на событие PropertyChanged для каждого элемента коллекции. Подписку на событие PropertyChanged надо выполнить во всех методах, которые добавляют в коллекцию новые элементы. При удалении элемента из коллекции от подписки на его событие PropertyChanged необходимо отказаться. При подписке на событие PropertyChanged как обработчик события надо использовать метод класса с коллекцией. В этом методе события PropertyChanged, которые происходят в элементах коллекции, преобразуются в события класса, содержащего коллекцию. Для этого из информации, которую получает обработчик события PropertyChanged, формируются данные для нового события, которое бросается из класса-коллекции. События регистрируются в специальных классах-слушателях. Классслушатель должен отслеживать изменения только в тех объектах, которые входят в коллекцию.
Вариант 2. Требования к программе Определить новые версии классов Edition, Magazine и MagazineCollection из лабораторной работы 3. Новая версия класса Edition реализует интерфейс System.ComponentModel.INotifyPropertyChanged. Событие PropertyChanged из интерфейса System.ComponentModel.INotifyPropertyChanged происходит при изменении значений свойств класса Edition, связанных с тиражом и датой выхода издания. Название свойства, значение которого изменилось, событие PropertyChanged передает своим обработчикам через свойство PropertyName класса PropertyChangedEventArgs. Для информации о типе изменений, которые произошли в коллекциях, определить перечисление (enum) Update со значениями Add, Replace и Property.
Для события, которое бросают методы новой версии класса MagazineCollection, определить универсальный делегат MagazinesChangedHandler с сигнатурой: void MagazinesChangedHandler (object source, MagazinesChangedEventArgs args); Класс MagazinesChangedEventArgs, производный от класса System.EventArgs, содержит открытое автореализуемое свойство типа string с названием коллекции; открытое автореализуемое свойство типа Update с информацией о том, чем вызвано событие, – добавлением нового элемента в коллекцию, заменой элемента в коллекции или изменением данных элемента; открытое автореализуемое свойство типа string с названием свойства класса Magazine, которое является источником изменения данных элемента; для событий, порожденных добавлением или заменой элемента, значение свойства – пустая строка; открытое автореализуемое свойство типа TKey с ключом элемента, который был добавлен в коллекцию, заменил один из элементов коллекции или элемента, у которого были изменены данные; конструктор c параметрами типа string, Update, string и TKey для инициализации значений всех свойств класса; перегруженную версию метода string ToString(). В новую версию класса MagazineCollection добавить открытое автореализуемое свойство типа string с названием коллекции; метод bool Replace(Magazine mold, Magazine mnew) для замены в словаре Dictionary<TKey, Magazine> элемента со значением mold на элемент со значением mnew; если в словаре нет элемента со значением mold, метод возвращает значение false; событие MagazinesChanged типа MagazinesChangedHandler, которое происходит при добавлении нового элемента в коллекцию, замене элемента в коллекции или при изменении данных одного из ее элементов. Определить класс Listener, собирающий информацию об изменениях в классе MagazineCollection. Класс Listener содержит список из элементов типа ListEntry. Каждый элемент ListEntry содержит информацию об отдельном изменении объекта MagazineCollection, в результате которого произошло событие MagazinesChanged. Класс ListEntry содержит автореализуемые свойства типа string с названием коллекции; типа Update c информацией о типе события;
типа string с названием свойства класса Magazine, которое явилось причиной изменения данных элемента; типа string с текстовым представлением ключа добавленного, удаленного или измененного элемента; конструктор для инициализации всех свойств класса; перегруженную версию метода string ToString(). Класс Listener содержит закрытое поле типа System.Collections.Generics.List; обработчик события MagazinesChanged, который на основе информации из объекта MagazinesChangedEventArgs, создает элемент ListEntry и добавляет его к списку; перегруженную версию метода string ToString() для формирования строки с информацией обо всех элементах списка List. В методе Main()
- Создать два объекта MagazineCollection с разными названиями.
- Создать объект типа Listener и подписать его на события MagazinesChanged из обоих объектов MagazineCollection.
- Внести изменения в MagazineCollection: добавить элементы в коллекции; изменить значения разных свойств элементов, входящих в коллекцию; заменить один из элементов коллекции; изменить данные в элементе, который был удален из коллекции при замене элемента.
- Вывести данные объекта Listener.