- •Лабораторная работа: События и команды в wpf
- •Обзор библиотечных событий
- •Упражнение 1. Обработка событий клавиатуры
- •События мыши
- •Упражнение 2. Прослушивание событий мыши
- •Упражнение 3. Создание и прослушивание пользовательского события
- •Обработчики уровня класса
- •Добавление информации в объект аргумента события
- •Задание для Упражнения 3
- •Модель команд
- •Объекты команд
- •Библиотечные классы команд
- •Присоединение команды к источнику
- •Привязка команды к прослушивающему элементу
- •Упражнение 4. Привязка команд в разметке
- •Перекрытие функций диспетчеризации событий
- •Прямой вызов команд
- •Упражнение 5. Привязка команд в процедурном коде
- •Жесты как источники команд
- •Добавление жестов в команду
- •Способ 1
- •Способ 2
- •Способ 3
- •Добавление жестов в прослушивающий элемент
- •Упражнение 6. Разработка простого блокнота без механизма команд
- •Создание главного меню
- •Добавление иконок
- •Создание логических ресурсов
- •Создание панели инструментов, строки состояния и рабочей области
- •Замена встроенного контекстного меню
- •Назначение ресурсов неразделяемыми
- •Замена иконок на прозрачные
- •Отключение встроенных команд
- •Подключение иконки приложения
- •Распределение класса по нескольким файлам и создание вспомогательных функций
- •Размещение вариантов заголовков окна в ресурсах приложения
- •Создание заготовок обработчиков
- •Регистрация обработчиков в разметке
- •Реализация обработчиков раздела меню File
- •Обработка системной кнопки
- •Реализация части обработчиков раздела меню Edit
- •Разработка и кодирование диалогового окна Find and Replace
- •Кодирование функциональности Find and Replace в основном окне
- •Подключение функциональности Find and Replace к источникам задач
- •Разработка диалогового окна Go To
- •Применение вложенных ресурсов
- •Подключение функциональности Go To к основному окну
- •Прочие задачи
- •Принудительная перерисовка окна
- •Добавление жестов
- •Логика отключения источников задач
- •Реализация логики отключения источников задачи Save
- •Упражнение 7. Разработка простого блокнота с использованием механизма команд
- •Создание нового проекта из копии существующего
- •Краткий анализ задачи
- •Создание и привязка команд
- •Реализация логики доступности источников команд
- •Отображение позиции курсора в строке состояния
Добавление информации в объект аргумента события
Объект 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.
Запустите приложение, должен получиться такой результат
Стратегия маршрутизации: Bubble
1) MyButton: Наблюдаю событие Tap.
Получил сообщение: Привет студентам от Снеткова!
2) UniformGrid: Суперобработчик события Tab
3) UniformGrid: Наблюдаю событие Tap.
Получил сообщение: Привет студентам от MyButton и MyButton!
4) Grid: Наблюдаю событие Tap.
Получил сообщение: Привет студентам от UniformGrid и MyButton!
5) DockPanel: Наблюдаю событие Tap.
Получил сообщение: Привет студентам от Grid и MyButton!
6) Window1: Суперобработчик события Tab
7) Window1: Наблюдаю событие Tap.
Получил сообщение: Привет студентам от DockPanel и MyButton!
