Выбрать главу

Класс sender

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

// Класс, создающий событие. Потомок класса ArrayList.

public class ListWithChangedEvent: ArrayList

{

     //Свойства класса: событие и его аргументы

     //Событие Changed, зажигаемое при всех изменениях

     //элементов списка.

     public event ChangedEventHandler Changed;

     //Аргументы события

     private ChangedEventArgs evargs = new ChangedEventArgs();

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

Хороший стиль требует задания в классе процедуры On, включающей событие. Так и поступим:

//Методы класса: процедура On и переопределяемые методы.

//Процедура On, включающая событие

protected virtual void OnChanged(ChangedEventArgs args)

{

       if (Changed!= null)

           Changed (this, args);

}

Процедура OnChanged полностью соответствует ранее описанному образцу, поэтому не требует дополнительных комментариев.

Наш класс, являясь наследником класса ArrayList, наследует все его методы. Переопределим методы, изменяющие элементы:

• метод Add, добавляющий новый элемент в конец списка;

• индексатор this, дающий доступ к элементу списка по индексу;

• метод Clear, производящий чистку списка.

//Переопределяемые методы, вызывающие событие Changed

//Добавление нового элемента

//при получении разрешения у обработчиков события

public override int Add (object value)

{

    int i=0;

    evargs.Item = value;

    OnChanged(evargs);

    if (evargs.Permit)

        i = base.Add(value);

     else

        Console.WriteLine("Добавление элемента запрещено." +

             "Значение = {0}", value);

     return i;

}

public override void Clear()

{

     evargs.Item=0;

     OnChanged(evargs);

     base.Clear();

}

public override object this[int index]

{

     set

     {

         evargs.Item = value;

         OnChanged(evargs);

         if (evargs.Permit)

             base[index] = value;

         else

             Console.WriteLine("Замена элемента запрещена." +

                 " Значение = {0}", value);

      }

      get{return(base[index]);}

}

Обратите внимание на схему включения события, например, в процедуре Add. Вначале задаются входные аргументы, в данном случае Item. Затем вызывается процедура включения OnChanged. При зажигании выполнение процедуры Add прерывается. Запускаются обработчики, присоединенные к событию. Процедура Add продолжит работу только после окончания их работы. Анализ выходной переменной Permit позволяет установить, получено ли разрешение на изменение значения; при истинности значения этой переменной вызывается родительский метод Add, осуществляющий изменение значения. Это достаточно типичная схема работы с событиями.

Классы receiver

Мы построим два класса, объекты которых способны получать и обрабатывать событие Changed. Получать они будут одно и то же сообщение, а обрабатывать его будут по-разному. В нашей модельной задаче различие обработчиков сведется к выдаче разных сообщений. Поэтому достаточно разобраться с устройством одного класса, названного EventReceiver1. Вот его код:

class EventReceiver1

{

     private ListWithChangedEvent List;

     public EventReceiveri(ListWithChangedEvent list)

     {

        List = list;

        // Присоединяет обработчик к событию.

        OnConnect ();

      }

     //Обработчик события — выдает сообщение.

     //Разрешает добавление элементов, меньших 10.

     private void ListChanged(object sender,

          ChangedEventArgs args)

      {

          Console.WriteLine("EventReceiveri: Сообщаю об изменениях: " + "Item ={0}", args.Item);

              args.Permit = ((int)args.Item < 10);

      }

      public void OnConnect ()

      {

           //Присоединяет обработчик к событию

           List.Changed += new ChangedEventHandler(ListChanged);

      }

       public void OffConnectO {

      {

          //Отсоединяет обработчик от события и удаляет список

          List.Changed — = new ChangedEventHandler(ListChanged);

          List = null;

      }

}//class EventReceiver1

Дам краткие комментарии.