Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Список делегатов — EventHandlerList




Дополнительные возможности при работе с делегатами

Здесь будут рассмотрены дополнительные возможности, предоставляемые общей библиотекой классов (FCL, Framework Class Library) для упрощения работы с делегатами. Некоторые из них могут быть весьма полезны в повседневном программировании.

В рамках компонентной модели общей библиотеки классов введен дополнительный класс EventHandlerList. Он предназначен для упрощения разработки компонентов, содержащих большое количество событий. Класс позволяет хранить в своем экземпляре неограниченное количество событий, организуя доступ к ним при помощи произвольных ключей типа Object. Наиболее интересные члены класса EventHandlerList описаны в таблице 2.

AddHandler Добавляет делегат в список по ключу
RemoveHanlder Изымает делегат из списка по ключу

Таблица 2. Члены класса System.ComponentModel.EventHandlerList.

По сути дела, список является и не списком вовсе, а ассоциативным массивом. Но основное его достоинство заключается не в этом. Главное его отличие от обычных коллекций состоит в том, что он производит добавление и изъятие элементов из списка, учитывая особенности делегатов. Операции добавления и изъятия производятся при помощи методов Combine и Remove. Таким образом, по одному ключу может храниться несколько скомбинированных однотипных делегатов. Соответственно, при изъятии делегата по заданному ключу, элемент списка будет удален не полностью, а произойдет рекомбинация делегата, в ходе которой некоторые из его ссылок будут потеряны. Но сам делегат может не истощиться, а содержать еще несколько ссылок. Такое поведение списка весьма удобно при разработке компонентов, предоставляющих пользователям множество событий. Можно попросту добавлять и удалять делегаты по заданным ключам, не задумываясь о дополнительной поддержке событий.

Продемонстрируем работу со списком на примере того же компонента кнопки (листинг 15). На этот раз он будет содержать два события, делегаты которых будут храниться в специализированном закрытом списке.

Листинг 15. Использование специализированной коллекции EventHandlerList при работе с делегатами.

using System;// Подключим пространство имен, отвечающее за поддержку компонентной// модели.using System.ComponentModel;// Опишем делегат с пустым прототипом.delegate void MyDelegate();// Введем тестовый класс/компонент.class Button{ // В этом закрытом списке будут храниться делегаты, // представляющие наши события. private EventHandlerList _eventHandlers; // Далее описаны два ключа, которые будут использоваться // для индексации элементов внутри списка. // Эти ключи определены с использованием идентификатора // readonly, поскольку необходима стопроцентная гарантия, // что ключи не изменят своего значения во время работы // программы, иначе работа программы будет непредсказуема. private static readonly object m_MouseUpKey = new Object(); private static readonly object m_MouseDownKey = new Object(); // Конструктор по умолчанию для класса. public Button() { // Инициализируем список. _eventHandlers = new EventHandlerList(); } // Опишем первое событие с поддержкой контроля. public event MyDelegate MouseUp { add { // Добавим делегат в список по ключу. _eventHandlers.AddHandler(m_MouseUpKey,value); } remove { // Удалим делегат из списка по ключу. _eventHandlers.RemoveHandler(m_MouseUpKey,value); } } // Опишем второе событие с поддержкой контроля. public event MyDelegate MouseDown { add { // Добавим делегат в список по ключу. _eventHandlers.AddHandler(m_MouseDownKey,value); } remove { // Удалим делегат из списка по ключу. _eventHandlers.RemoveHandler(m_MouseDownKey,value); } } // Данная функция будет вызывать первое событие. public void SimulateMouseUp() { // Получаем нужный делегат из нашего списка // при помощи ключа. MyDelegate eh = (MyDelegate)_eventHandlers[m_MouseUpKey]; // Проверяем, присоединены ли функции к делегату, полученному из // коллекции. В случае, если это так, вызываем делегат. if (eh!= null) eh(); } // А эта функция будет вызывать второе событие. public void SimulateMouseDown() { // Получаем нужный делегат из нашего списка // при помощи ключа. MyDelegate eh = (MyDelegate)_eventHandlers[m_MouseDownKey]; // Проверяем, присоединены ли функции к полученному // делегату. В случае, если это так, вызываем делегат. if (eh!= null) eh(); }}; class App{ public static void Main() { // Создаем экземпляр тестового класса. Button sc = new Button(); // Присоединяем обработчики к событиям. sc.MouseUp += new MyDelegate(HandlerMouseUp); sc.MouseDown += new MyDelegate(HandlerMouseDown); // Вызываем события sc.SimulateMouseUp(); sc.SimulateMouseDown(); } // Обработчик для первого события. public static void HandlerMouseUp() { // Уведомляем пользователя о произошедшем // событии выводом соответствующего сообщения // на консоль. Console.WriteLine("HandlerUp was called"); } // Обработчик для второго события. public static void HandlerMouseDown() { // Уведомляем пользователя о произошедшем // событии выводом соответствующего сообщения // на консоль. Console.WriteLine("HandlerDown was called"); }};

В результате работы приложения на консоль будут выведены следующие строки.

HandlerUp was calledHandlerDown was called

Как видно, нововведение никоим образом не отразилось на использовании класса извне. Была всего лишь изменена внутренняя организация компонента, несколько упростив работу программистам при помощи специализированного хранилища делегатов.




Поделиться с друзьями:


Дата добавления: 2014-01-07; Просмотров: 268; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.01 сек.