eventhandler c что это

События и делегаты

В Заметке о консольных и оконных (Windows Forms) приложениях мы отметили существенную разницу между ними. Консольное приложение реализует концепцию императивного (процедурного) программирования, а управление Windows-приложением основано на понятии события (event). События могут создаваться как пользователем, так и возникать в процессе выполнения приложения. Начнем с простых вещей.

Создадим оконное приложение и запустим его на выполнение. С пустой формой мы можем выполнить только несколько стандартных действий: изменить размер, свернуть, свернуть в окно/развернуть и закрыть приложение.

Для изменения размеров формы подведем указатель мыши (1 событие) к любой ее границе (указатель изменит свою форму), перетянем ее в нужном направлении (2 событие) и отпустим кнопку (3 событие). Последние три действия с формой выполняются после клика мышью (событие 4) на кнопках формы.

Ясно, что такое приложение нам не слишком интересно, тем не менее, очевидна связь между событиями и действиями.

Перенесем с Панели элементов на форму объект «Кнопка» (по умолчанию – button1 класса Button). На вкладке «Конструктор» кнопка видна, на вкладке «Код» о ней нет никакой информации. Однако раскрыв файл Form1.Designer.cs, мы увидим в описании класса Form1 поле:

private System.Windows.Forms.Button button1;

которое задает этот объект, а в методе private void InitializeComponent() обнаружим описание его свойств (имя, местоположение, размер, надпись и т.п.).

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

Смотрим книгу «для чайников». В ней написано: чтобы связать это событие с каким-либо действием необходимо всего лишь выполнить двойной клик на кнопке, в окне кода появится заготовка для метода – обработчика события Click:

private void button1_Click(object sender, EventArgs e)
<

>

Увеличим ширину кнопки примерно в три раза. Вставим в тело метода между фигурными скобками оператор:
button1.Text = DateTime.Now.ToString();
Теперь при нажатии кнопки непосредственно на ней мы можем прочитать текущие дату и время нажатия на кнопку.

«Выдающийся» результат! Есть событие, есть реакция на него (обработка события). Как Вам такая автоматизация программирования!

Заметим, что в панели Свойства для объекта button1 на закладке События (щелчок на «желтой молнии») напротив события Click появился метод button1_Click. В окне кода добавили всего один метод с одним оператором в его теле. Что же еще изменилось? Посмотрим содержимое файла Form1.Designer.cs. В нем добавилась загадочная строка:

this.button1.Click += new System.EventHandler(this.button1_Click);

Расшифруем ее. Ключевое слово this – это ссылка на текущий объект Form1 (забавно, что имя объекта совпадает с именем класса). Объект button1 размещен на форме Form1. А Click – очевидно это событие, клик на кнопке. EventHandlerделегат (delegate), представляет метод, который будет обрабатывать событие, не имеющее данных (объявлен в библиотеке System). Тип события обязательно должен совпадать с типом делегата. В скобках указывается имя этого метода button1_Click.
Переведем смысл оператора на русский язык:
Объект.Событие += new Делегат(Метод_обработки);
Символ + определяет подписку обработчика события.
Очевидный вывод: Подписка на событие с использованием делегата приводит к вызову метода при возникновении события.

Возможен ли разрыв связи между событием и методом его обработки? И нет ли у вас ощущения статичности таких связей? Можно ли то же самое достичь программным путем?

Читайте также:  что делает nokk в радуге

Заметим, что этот файл Form1.Designer.cs является текстовым описанием формы и размещенных на ней элементов после запуска программы, что позволяет отобразить ее в режиме конструктора.

Далее многое можно изменять программным путем.

Итак, событие – это сообщение другим объектам программы, что произошло какое-то действие. Действие может быть инициировано пользователем (нажатие клавиши) или же в результате выполнения какого-то фрагмента программы (по условию).

Объект, который вызывает событие, называется отправителем (sender) сообщения, а объект, который сообщение получает – получателем. Роль «почтальона» выполняет делегат. Получатель сообщения имеет метод, который автоматически выполняется в ответ на исходное событие. В нашем примере отправителем и получателем сообщения является объект button1 («makes himself»).

Событием в языке C# называется сущность, предоставляющая две возможности: сообщать об изменениях, а для его пользователей — реагировать на них. В объявлениях классов визуальных компонентов мы найдем большое количество событий, которые могут быть вам полезны. Подсчитайте, сколько событий связано с формой? У меня получилось – 76. А для кнопки – 58, не мало? Если же вам необходимо создать собственное событие, то вы можете его просто объявить:

public event EventHandler myEvent;

Рассмотрим, из чего состоит объявление. Сначала идут модификаторы события, затем ключевое слово event, после него — тип события, который обязательно должен быть типом-делегатом, и идентификатор события, то есть его имя myEvent. Ключевое слово event сообщает компилятору о том, что это не публичное поле, а специальным образом раскрывающаяся конструкция, скрывающая от программиста детали реализации механизма событий (пока это замечание пропустите).

void обработчик(object отправитель, EventArgs е)

Пример использования обобщенного делегата EventHandler

Обобщенный делегат EventHandler используется для
объявления события Ez:

public event EventHandler Ez;

Аргументы, передаваемые в метод, задаются в классе MyEA, который наследуется от класса EventArgs.

Постановка задачи «Управление размерами и цветом формы»

Набор цветов: Red, Green, Blue, Yellow + исходный (добавляйте любые!)
Размеры: 500х150, 550×200, 600×250, 650×300

Элементы управления:
Кнопка button1 — Разрешение/Запрет изменение свойств формы
Кнопка button2 — Перекраска формы в желтый цвет без ограничений
Элемент comboBox1 — для выбора цвета: Red, Green, Blue, прежний
Метка label1 — подсказка: «Выберите цвет закраски формы» к comboBox1.

Начальная форма может выглядеть так:

Создаются два класса:
1) Класс Моих Событий Аргументы:

2) Мой класс Обработка события:

Далее приводится текст файла Form1.cs с комментариями:

Вид формы после перекраски:

Примеры

Другой пример применения делегатов рассмотрен в посте «Делегаты и методы».

Источник

Event Handler Args> Делегат

Определение

Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.

Представляет метод, обрабатывающий событие, когда событие предоставляет данные.

Параметры типа

Тип данных события, создаваемых событием.

Параметры

Объект, содержащий данные о событии.

Примеры

Комментарии

Делегат, который ссылается на метод, который предоставляет ответ на событие.

При необходимости — класс, содержащий данные события, если событие предоставляет данные.

Делегат — это тип, определяющий сигнатуру, то есть тип возвращаемого значения и типы списка параметров для метода. Можно использовать тип делегата для объявления переменной, которая может ссылаться на любой метод с той же сигнатурой, что и делегат.

Читайте также:  какой нужен кабель чтобы подключить компьютер к телевизору

Стандартная сигнатура делегата обработчика событий определяет метод, который не возвращает значение. Первый параметр этого метода имеет тип Object и ссылается на экземпляр, который вызывает событие. Второй параметр является производным от типа EventArgs и содержит данные события. Если событие не создает данные события, второй параметр — это просто значение EventArgs.Empty поля. В противном случае второй параметр является типом, производным от, EventArgs и предоставляет все поля или свойства, необходимые для хранения данных события.

Чтобы связать событие с методом, который будет выполнять обработку события, добавьте в событие экземпляр делегата. Обработчик событий вызывается всякий раз, когда происходит событие, если делегат не удален.

Дополнительные сведения о делегатах обработчиков событий см. в разделе обработка и вызов событий.

Методы расширения

Получает объект, представляющий метод, представленный указанным делегатом.

Источник

События в C# и их вызов

События в C# позволяют классу или объекту уведомлять другие классы или объекты о возникновении каких-либо ситуаций. События активно используются в Windows-приложениях. Класс, который порождает (отправляет) событие, называется издателем, а классы, обрабатывающие (принимающие) событие, называются подписчиками. Соответственно, на одно и то же событие могут подписываться несколько подписчиков.

События в C#

Итак, вспомним наш класс Person, который мы использовали, когда разбирали тему использования делегатов. Итоговый класс у нас выглядел следующим образом:

Использование метода ChangeDepartmnet в данном случае хоть и возможно, но избыточно. Более логично, в данном случае, позволить пользователю класса менять свойство Department как и другие свойства и, при этом, в своей программе «отлавливать» момент изменения этого свойства и выводить результат в консоль. И здесь-то нам и помогут события в C#.

В C# событие определяется следующим образом:

Технически, зная то, что из себя представляет делегат в C# и как он определяется, мы можем определить делегат для нашего события в любом удобном для нас виде, хоть так:

и затем объявить вот такое событие:

И наш код будет работать, НО правильным и хорошим тоном считается придерживаться следующего правила: делегат события содержит два параметра — первый предоставляет подписчику информацию об издателе, а второй — наследник класса EventArgs передает подписчику необходимые параметры. Попробуем переписать наш класс Person и создать свое первое событие в C#

Создание события в C#

Перепишем наш класс Person следующим образом:

Обратим внимание на следующие моменты:

Теперь мы можем подписаться на это событие и получать уведомления от издателя. Сделать это можно, например, так:

Подписка на события в C#

На любое событие в C# может быть подписано любое количество подписчиков. Более того, один и тот же класс может подписаться любое количество раз на событие:

Как и в случае работы с обычными делегатами, методы EventHandler и EventHandler_2 будут вызваны последовательно:

Создание собственных делегатов событий в C#

Но что, если нам потребуется, чтобы событие ChangeDepartment сообщало нам не только факт смены отдела, но и то, какой отдел был ранее? Здесь нам поможет создание собственного делегата события. Делается это следующим образом:

Во-первых, создаем класс-наследник EventArgs который будет содержать необходимые параметры. Например, можем определить такой класс:

Читайте также:  Что значит трасса е30

Во-вторых, объявляем делегат для события:

В третьих, определяем событие в классе:

В-четвертых, обеспечить внутри класса вызов события:

Нам остается только подписаться на событие и получать сообщения от издателя. Ниже показан код основной программы:

Итого

Источник

Event Handler Делегат

Определение

Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.

Представляет метод, обрабатывающий событие, не имеющее данных.

Параметры

Объект, не содержащий данных события.

Примеры

Комментарии

Делегат, определяющий метод, который предоставляет ответ на событие.

При необходимости — класс, содержащий данные события, если событие предоставляет данные.

Делегат — это тип, определяющий сигнатуру, то есть тип возвращаемого значения и типы списка параметров для метода. Можно использовать тип делегата для объявления переменной, которая может ссылаться на любой метод с той же сигнатурой, что и делегат.

Стандартная сигнатура делегата обработчика событий определяет метод, который не возвращает значение. Первый параметр этого метода имеет тип Object и ссылается на экземпляр, который вызывает событие. Второй параметр является производным от типа EventArgs и содержит данные события. Если событие не создает данные события, второй параметр — это просто значение EventArgs.Empty поля. В противном случае второй параметр является типом, производным от, EventArgs и предоставляет все поля или свойства, необходимые для хранения данных события.

EventHandlerДелегат — это предопределенный делегат, который специально представляет метод обработчика событий для события, которое не создает данные. Если событие создает данные, необходимо использовать универсальный EventHandler класс делегата.

Чтобы связать событие с методом, который будет выполнять обработку события, добавьте в событие экземпляр делегата. Обработчик событий вызывается всякий раз, когда происходит событие, если делегат не удален.

Дополнительные сведения о делегатах обработчиков событий см. в разделе обработка и вызов событий.

Методы расширения

Получает объект, представляющий метод, представленный указанным делегатом.

Источник

Имя EventHandler может привести к путанице, так как на самом деле этот делегат не обрабатывает событие. Делегат EventHandler и универсальный делегат EventHandler являются типами делегатов. Метод или лямбда-выражение, сигнатура которого соответствует определению делегата, является обработчиком событий и будет вызываться при возникновении события.

Публикация событий, основанных на шаблоне EventHandler

(Пропустите этот шаг и перейдите к шагу 3a, если не нужно отправлять пользовательские данные с определенным событием.) Объявите класс для пользовательских данных в области, видимой для классов Publisher и Subscriber. Затем добавьте необходимые члены для хранения пользовательских данных о событиях. В этом примере возвращается простая строка.

Объявите событие в своем классе публикации, выполнив одно из следующих действий.

Если у вас нет пользовательского класса EventArgs, тип события будет неуниверсальным делегатом EventHandler. Нет необходимости объявлять делегат, так как он уже объявлен в пространстве имен System, которое включается при создании проекта C#. Добавьте следующий код в класс Publisher.

Если вы используете неуниверсальную версию EventHandler и имеется пользовательский класс, производный от EventArgs, объявите событие внутри класса публикации и используйте делегат из шага 2 в качестве типа.

Пример

В следующем примере показана вышеописанная процедура с использованием пользовательского класса EventArgs и EventHandler в качестве типа событий.

Источник

Сказочный портал