События

При разработке программ (это особенно очевидно для оконных приложений) довольно часто возникает потребность в том, чтобы в данной части программы как-то среагировать на событие, произошедшее в другой части программы. Например, при нажатии на клавишу мыши вывести какое-либо сообщение в окне программы или графическое изображение, т.е. здесь при нажатии на клавишу происходит событие (event) и на него реагирует специальная функция — обработчик этого событий (event handler).

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

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

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

Для работы с событием в программе необходимо выполнить следующие действия:

1)Объявить тип делегата события:

delegate тип_возвращаемого_значения тип_делегата_события (список_формальных_параметров);

где

2)Объявить ссылку на событие:

event тип_делегата_события ссылка_на_событие;

где

Ссылка на событие чаще всего объявляется в классе — источнике события, но может объявляться и вне этого класса.

3)В классе — источнике события необходимо объявить открытый метод, в котором будет активироваться событие. Формат этого метода следующий:

public void имя_метода()

{

   if(ссылка_на_событие != null)

   {

      ссылка_на_событие();

   }

}

В этом методе обязательно должен присутствовать условный оператор. Нельзя активировать событие до тех пор, пока не будет установлена связь между источником и приёмником события!

4)В классе-приёмнике события необходимо записать метод по обработке события.

5)Теперь можно использовать событие. Создаём объект-источник и объект-приёмник, регистрируем обработчик события и генерируем событие. Обработчик события должен его выполнить.

Пример. Создадим простейший пример программы, в которой объект класса A (это источник) будет генерировать событие, а объект класса B (это приёмник) — обрабатывать данное событие.

Текст программы:

using System;

namespace Prim_Event

{

   public delegate void Del();

   class A

   {

      public event Del genEv;

      public void F()

      {

         if(genEv != null)

         {

            genEv();

         }

      }

   }

   class B

   {

      public void HandlerEv()

      {

         Console.WriteLine("Объект класса B получил сообщение");

      }

   }

   class Program

   {

      public static void Main(string[] args)

      {

         Console.WriteLine("Тест событие:\n");

    // 1)Создаём объект-источник события:

         A x = new A();

    // 2)Создаём объект-приёмник события:

         B y = new B();

    // 3)Добавляем обработчик события

    //   (здесь объект y подписывается на сообщение

    //   объекта x и гарантирует, что будет на событие

    //   genEv выполнять обработчик HandlerEv)

         x.genEv += new Del(y.HandlerEv);

    // 4)Генирируем событие:

         x.F();

         Console.Write("Press any key to continue . . . ");

         Console.ReadKey(true);

      }

   }

}

Результаты работы программы:

Тест событие:


Объект класса B получил сообщение

Press any key to continue . . .

Замечание. Разработчиками библиотеки .NET создано большое количество стандартных делегатов, предназначенных для реализации механизма обработки событий. Обычно они оформлены по таким правилам:

  1. имя делегата заканчивается суффиксом EventHandler;

  2. делегат имеет два параметра: первый параметр имеет тип object и определяет объект-источник, второй параметр имеет тип EventArgs и служит для задания дополнительной информации.

Как следствие, обработчики событий имеют вид:

public void Имя_обработчика(object sendler, EventArgs e)

{

   // необходимые действия

}

Чаще всего в обработчике используется второй параметр, например, в типичном обработчике события по перерисовке окна формы, используя второй параметр, мы добираемся до полотна (свойство Graphics), на которое выводится изображение:

void MainFormPaint(object sender, PaintEventArgs e)

{

   Graphics g = e.Graphics;

   // перерисовка объектов в окне формы,

   // например, рисуем линию:

   g.DrawLine(new Pen(Color.Red), 10,10,100,50);

}



Назад
На верх
Вперёд
Hosted by uCoz