Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Класс sender






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

/// < summary> /// Класс, создающий событие. /// Потомок класса ArrayList. /// < /summary> public class ListWithChangedEvent: ArrayList { string name; //имя объекта public event ChangedEventHandler Changed; //событие bool permit; //результат обработки события /// < summary> /// Конструктор /// < /summary> /// < param name=" name" > имя объекта< /param> public ListWithChangedEvent(string name) { this.name = name; } public string Name { get { return name; } }

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

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

/// < summary> /// Процедура On, включающая событие/// < /summary> /// < param name=" args" > аргументы события< /param> protected virtual void OnChanged(ChangedEventArgs args) { if (Changed! = null) Changed(this, args); }

Процедура OnChanged соответствует ранее описанному образцу. Если список обработчиков не пуст, то зажигается событие - посылается сообщение всем обработчикам события. Синтаксически конструкция Changed(this, args) - это вызов списка методов, поскольку Changed - объект функционального типа, к которому прикреплен список последовательно работающих методов.

Если в списке аргументов args есть выходные аргументы, то для решения проблемы коллизии совместной работы обработчиков посылку сообщения обработчикам события следует устроить более сложным образом:

protected virtual void OnChanged(ChangedEventArgs args) { int countYes = 0, countNo = 0; if (Changed! = null) { foreach (ChangedEventHandler del in Changed.GetInvocationList()) { del(this, args); if (args.Permit) countYes++; else countNo++; } permit = (countYes > = countNo); } }

Метод GetInvocationList позволяет получить список обработчиков события, а цикл foreach - вызывать один обработчик за другим. После того, как обработчик завершится, можно понять, каково значение сформированного выходного аргумента события. В данном примере окончательное решение принимается по большинству голосов. Счетчики countYes и countNo считают голоса " за" и " против". Представленное здесь решение демонстрирует корректный способ работы с событиями, когда обработчикам необходимо передавать входные и выходные аргументы.

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

  • метод Add, добавляющий новый элемент в конец списка;
  • индексатор this, дающий доступ к элементу списка по индексу;
  • метод Clear, производящий чистку списка.
// Переопределяемые методы, вызывающие событие Changed public override int Add(object value) { int index = -1; ChangedEventArgs evargs = new ChangedEventArgs(name, value); OnChanged(evargs); if (permit) index = base.Add(value); return index; }

Обратите внимание на схему включения события в процедуре Add. Вначале создается объект evargs - аргументы события, который передается методу OnChanged. Этот метод поочередно вызовет обработчики события и сформирует итоговый результат их работы. Анализ переменной permit позволяет установить, получено ли разрешение на изменение значения. При истинности значения этой переменной вызывается родительский метод Add, осуществляющий изменение значения. Аналогично устроены и другие методы, в которых возникает событие Changed.

public override void Clear() { ChangedEventArgs evargs = new ChangedEventArgs(name, 0); OnChanged(evargs); base.Clear(); } public override object this[int index] { set { ChangedEventArgs evargs = new ChangedEventArgs(name, value); OnChanged(evargs); if (permit) base[index] = value; } get {return(base[index]); }}

Это достаточно типичная схема организации класса с событиями.






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.