Полезное:
Как сделать разговор полезным и приятным
Как сделать объемную звезду своими руками
Как сделать то, что делать не хочется?
Как сделать погремушку
Как сделать так чтобы женщины сами знакомились с вами
Как сделать идею коммерческой
Как сделать хорошую растяжку ног?
Как сделать наш разум здоровым?
Как сделать, чтобы люди обманывали меньше
Вопрос 4. Как сделать так, чтобы вас уважали и ценили?
Как сделать лучше себе и другим людям
Как сделать свидание интересным?
Категории:
АрхитектураАстрономияБиологияГеографияГеологияИнформатикаИскусствоИсторияКулинарияКультураМаркетингМатематикаМедицинаМенеджментОхрана трудаПравоПроизводствоПсихологияРелигияСоциологияСпортТехникаФизикаФилософияХимияЭкологияЭкономикаЭлектроника
|
Применение аксессоров событий
В приведенных выше примерах события формировались в форме, допускавшей автоматическое управление списком вызовов обработчиков событий, включая добавление и удаление обработчиков событий из списка. Поэтому управление этим списком не нужно было организовывать вручную. Благодаря именно этому свойству такие события используются чаще всего. Тем не менее организовать управление списком вызовов обработчиков событий можно и вручную, чтобы, например, реализовать специальный механизм сохранения событий. Для управления списком обработчиков событий служит расширенная форма оператора event, позволяющая использовать аксессоры событий. Эти аксессоры предоставляют средства для управления реализацией подобного списка в приведенной ниже форме. event делегат_события имя_события { add { // Код добавления события в цепочку событий. } remove { // Код удаления события из цепочки событий. } } В эту форму входят два аксессора событий: add и remove. Аксессор add вызывается, когда обработчик событий добавляется в цепочку событий с помощью оператора +=. В то же время аксессор remove вызывается, когда обработчик событий удаляется из цепочки событий с помощью оператора -=. Когда вызывается аксессор add или remove, он принимает в качестве параметра добавляемый или удаляемый обработчик. Как и в других разновидностях аксессоров, этот неявный параметр называется value. Реализовав аксессоры add или remove, можно организовать специальную схему хранения обработчиков событий. Например, обработчики событий можно хранить в массиве, стеке или очереди. Ниже приведен пример программы, демонстрирующей аксессорную форму события. В ней для хранения обработчиков событий используется массив. Этот массив состоит всего из трех элементов, поэтому в цепочке событий можно хранить одновременно только три обработчика. // Создать специальные средства для управления списками // вызова обработчиков событий. using System; // Объявить тип делегата для события. delegate void MyEventHandler(); // Объявить класс для хранения максимум трех событий. class MyEvent { MyEventHandler[] evnt = new MyEventHandler[3]; public event MyEventHandler SomeEvent { // Добавить событие в список. add { int i; for (i = 0; i < 3; i++) if (evnt[i] == null) { evnt[i] = value; break; } if (i == 3) Console.WriteLine("Список событий заполнен."); } // Удалить событие из списка. remove { int i; for (i = 0; i < 3; i++) if (evnt[i] == value) { evnt[i] = null; break; } if (i == 3) Console.WriteLine("Обработчик событий не найден."); } } // Этот метод вызывается для запуска событий. public void OnSomeEvent() { for (int i = 0; i < 3; i++) if (evnt[i]!= null) evnt[i](); } } // Создать ряд классов, использующих делегат MyEventHandler. class W{ public void Whandler(){ Console.WriteLine("Событие получено объектом W"); } } class X { public void Xhandler() { Console.WriteLine("Событие получено объектом X"); } } class Y { public void Yhandler() { Console.WriteLine("Событие получено объектом Y"); } } class Z { public void Zhandler() { Console.WriteLine("Событие получено объектом Z"); } } class EventDemo5 { static void Main() { MyEvent evt = new MyEvent(); W wOb = new W(); X xOb = new X(); Y yOb = new Y(); Z zOb = new Z(); // Добавить обработчики в цепочку событий. Console.WriteLine("Добавление событий. "); evt.SomeEvent += wOb.Whandler; evt.SomeEvent += xOb.Xhandler; evt.SomeEvent += yOb.Yhandler; // Сохранить нельзя - список заполнен. evt.SomeEvent += zOb.Zhandler; Console.WriteLine(); // Запустить события. evt.OnSomeEvent(); Console.WriteLine(); // Удалить обработчик. Console.WriteLine("Удаление обработчика xOb.Xhandler."); evt.SomeEvent -= xOb.Xhandler; evt.OnSomeEvent(); Console.WriteLine(); // Попробовать удалить обработчик еще раз. Console.WriteLine("Попытка удалить обработчик " + "xOb.Xhandler еще раз."); evt.SomeEvent -= xOb.Xhandler; evt.OnSomeEvent(); Console.WriteLine(); // Атеперь добавить обработчик Zhandler. Console.WriteLine("Добавление обработчика zOb.Zhandler."); evt.SomeEvent += zOb.Zhandler; evt.OnSomeEvent(); } } Добавление событий. Список событий заполнен.
Событие получено объектом W Событие получено объектом X Событие получено объектом Y
Удаление обработчика xOb.Xhandler. Событие получено объектом W Событие получено объектом Y
Попытка удалить обработчик xOb.Xhandler еще раз. Обработчик событий не найден. Событие получено объектом W Событие получено объектом Y
Добавление обработчика zOb.Zhandler. Событие получено объектом W Событие получено объектом X Событие получено объектом Y Рассмотрим данную программу более подробно. Сначала в ней определяется делегат обработчиков событий MyEventHandler. Затем объявляется класс MyEvent. В самом его начале определяется массив обработчиков событий evnt, состоящий из трех элементов. MyEventHandler[] evnt = new MyEventHandler[3]; Этот массив служит для хранения обработчиков событий, добавляемых в цепочку событий. По умолчанию элементы массива evnt инициализируются пустым значением (null). Далее объявляется событие SomeEvent. В этом объявлении используется приведенная ниже аксессорная форма оператора event. public event MyEventHandler SomeEvent { // Добавить событие в список. add { int i; for (i = 0; i < 3; i++) if (evnt[i] == null) { evnt[i] = value; break; } if (i == 3) Console.WriteLine("Список событий заполнен."); } // Удалить событие из списка. remove { int i; for (i = 0; i < 3; i++) if (evnt[i] == value) { evnt[i] = null; break; } if (i == 3) Console.WriteLine("Обработчик событий не найден."); } } Когда в цепочку событий добавляется обработчик событий, вызывается аксессор add, и в первом неиспользуемом (т.е. пустом) элементе массива evnt запоминается ссылка на этот обработчик, содержащаяся в неявно задаваемом параметре value. Если в массиве отсутствуют свободные элементы, то выдается сообщение об ошибке. (Разумеется, в реальном коде при переполнении списка лучше сгенерировать соответствующее исключение.) Массив evnt состоит всего из трех элементов, поэтому в нем можно сохранить только три обработчика событий. Когда же обработчик событий удаляется из цепочки событий, то вызывается аксессор remove и в массиве evnt осуществляется поиск ссылки на этот обработчик, передаваемой в качестве параметра value. Если ссылка найдена, то соответствующему элементу массива присваивается пустое значение (null), а значит, обработчик удаляется из цепочки событий. При запуске события вызывается метод OnSomeEvent(). В этом методе происходит циклическое обращение к элементам массива evnt для вызова по очереди каждого обработчика событий. Как демонстрирует рассматриваемый здесь пример программы, механизм хранения обработчиков событий нетрудно реализовать, если в этом есть потребность. Но для большинства приложений более подходящим оказывается используемый по умолчанию механизм хранения обработчиков событий, который обеспечивает форма оператора event без аксессоров. Тем не менее аксессорная форма оператора event используется в особых случаях. Так, если обработчики событий необходимо выполнять в программе в порядке их приоритетности, а не в том порядке, в каком они вводятся в цепочку событий, то для их хранения можно воспользоваться очередью по приоритету. Date: 2015-09-02; view: 444; Нарушение авторских прав |