Добавление информации в объект аргумента события

Объект RoutedEventArgs, который мы передали событию при возбуждении в перекрытом методе OnClick() несет в себе только ту информацию, которую предусмотрели разработчики библиотеки. Мы можем добавить свою информацию к нашему события, если расширим класс RoutedEventArgs.

Поскольку стандартный делегат

public delegate void RoutedEventHandler(object sender, RoutedEventArgs e)

задает сигнатуру обработчиков такую, что второй аргумент ожидает ссылку на объект RoutedEventArgs, то ссылку на более толстый объект-расширение обработчик события примет спокойно. Но нужно иметь ввиду, для того, чтобы добраться до членов расширения переданного в обработчик объекта, необходимо будет повысить полномочия ссылки до нашего толстого объекта.

  • Добавьте в самый конец файла MyButton.cs после всего существующего кода следующее расширение библиотечного класса RoutedEventArgs объекта-аргумента события
namespace UserEvents{ // Расширяем класс аргументов class MyEventArgs : RoutedEventArgs { // Соблюдаем сигнатуру родителя public MyEventArgs(RoutedEvent routedEvent) : base(routedEvent) { } string message;// Базовое поле свойства public string Message // Свойство чтения/записи { get { return message; } set { message = value; } } }}

Здесь в расширение мы скромно добавили только одно свойство вместе с базовым полем хранения данных. Но при необходимости можно добавить любое количество членов расширения.

  • Модифицируйте перекрытый метод OnClick() так, чтобы в возбуждаемое событие передавался объект-расширение с начальным значением нового свойства
// Перекроем метод щелчка базовой кнопки для возбуждения события protected override void OnClick() { count = 0; // Сбрасываем счетчик //Console.Clear(); // Очищаем консоль //base.RaiseEvent(new RoutedEventArgs(MyButton.TapEvent));// Возбуждаем событие // Добавляем информацию и отсылаем MyEventArgs myEventArgs = new MyEventArgs(MyButton.TapEvent); myEventArgs.Message = "Привет студентам от Снеткова!"; base.RaiseEvent(myEventArgs);// Возбуждаем событие }
  • Модифицируйте в файле Window1.xaml.cs вспомогательную функцию ShowTap() следующим образом
void ShowTap(object obj, RoutedEventArgs args) { if (MyButton.count == 0) { System.Diagnostics.Debug.WriteLine( String.Format("\n\t Стратегия маршрутизации: {0}", args.RoutedEvent.RoutingStrategy)); } String typeName = obj.GetType().Name; /* System.Diagnostics.Debug.WriteLine( String.Format("{0}) {1}: Наблюдаю событие Tap", ++MyButton.count, typeName)); */ // Повышаем полномочия ссылки и извлекаем сообщение MyEventArgs e = args as MyEventArgs; string message = e.Message; // Выводим информацию System.Diagnostics.Debug.WriteLine( String.Format("{0}) {1}: Наблюдаю событие Tap.\n" + "\tПолучил сообщение: {2}", ++MyButton.count, typeName, message)); // Изменяем информацию в объекте-аргументе e.Message = String.Format("Привет студентам от {0} и {1}!", typeName, args.RoutedEvent.OwnerType.Name); }

В каждом обработчике мы намеренно меняем значение свойства Message объекта-аргумента события на новое, чтобы подчеркнуть такую возможность. Один и тот же объект аргумента движется вместе с событием и последовательно попадает в подписанные на событие обработчики элементов, где и может быть изменен. Для получения доступа к свойству Message нашего объекта-аргумента предварительно нужно повысить полномочия ссылки базового типа RoutedEventArgs. Вспомним также, что в любом обработчике мы можем остановить дальнейшее продвижение события, присвоив свойству объекта-аргумента args. Handled значение true.