Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
course_(Windows&Web).docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
4.68 Mб
Скачать

Декларативные действия

Мы видим, что с появлением команд и слабой связи WPF движется в направлении модели, когда программа просто объявляет о своих пожеланиях (например, «я хочу, чтобы окно закрылось, когда вы отдадите эту команду») вместо реализации (например, «вызвать метод Window.Close() при нажатии этой кнопки»).

Одним из столпов WPF является идея декларативного программирования. Помимо визуальных элементов и структуры пользовательского интерфейса, в разметке можно выразить немалую долю программной логики. Декларативная логика особенно полезна, потому что, отталкиваясь от декларативного формата, мы часто можем предоставить более развитые инструменты и, возможно, более содержательные системные службы. Для разных способов обработки действий предусмотрены различные уровни поддержки в декларативной программе. Для событий можно в разметке объявить отвечающую на него функцию, но сам обработчик должен быть реализован в коде. Команды специально задуманы для декларативного использования, поскольку предлагают наилучшее отделение источника действия от его потребителя. У триггеров, пожалуй, самая развитая декларативная поддержка, но им недостает расширяемости, поэтому применять их для решения сложных задач затруднительно.

Все механизмы работы с действиями в той или иной мере поддерживают перечисленные выше принципы. Углубленное изучение действий мы начнем с наиболее известного: событий.

События

В WPF события ведут себя точно так же, как в любой другой библиотеке классов, входящей в состав .NET. Каждый объект предоставляет набор событий, на которые можно подписаться, определив соответствующий делегат. В WPF имеется дополнительный механизм маршрутизации событий, который позволяет им распространяться вверх по дереву элементов. Существует три вида маршрутизации событий: прямая, всплытие (bubbling) и туннелирование (tunneling). Прямые события – это простые события, возникающие от одиночного источника, они почти идентичны стандартным событиям .NET с тем отличием, что регистрируются в системе маршрутизации событий WPF. Некоторые средства платформы (например, триггеры) требуют, чтобы событие было явно зарегистрировано. Всплывающие и туннельные события – две стороны одной медали: туннельные события продвигаются от корня дерева к целевому элементу, а всплывающие – в обратном направлении. Обычно эти два вида событий встречаются попарно, причем туннельная версия имеет префикс Preview. Большинство событий ввода (от клавиатуры, от мыши и от пера) имеют как туннельную, так и всплывающую версии, например: MouseRightButtonDown и PreviewMouseRightButtonDown, соответственно.

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

<Window ... PreviewMouseRightButtonDown=’WindowPreviewRightButtonDown’ MouseRightButtonDown=’WindowRightButtonDown’> <GroupBox PreviewMouseRightButtonDown=’GroupBoxPreviewRightButtonDown’ MouseRightButtonDown=’GroupBoxRightButtonDown’> <StackPanel> <Button>One</Button> <Button PreviewMouseRightButtonDown=’ButtonTwoPreviewRightButtonDown’ MouseRightButtonDown=’ButtonTwoRightButtonDown’> Two </Button> </StackPanel> </GroupBox> </Window>

В обработчике каждого события мы можем вывести его имя:

void ButtonTwoPreviewRightButtonDown(object sender, MouseButtonEventArgs e) { Debug.WriteLine(«ButtonTwo PreviewRightButtonDown»); } void ButtonTwoRightButtonDown(object sender, MouseButtonEventArgs e) { Debug.WriteLine(«ButtonTwo RightButtonDown»); } void GroupBoxPreviewRightButtonDown(object sender, MouseButtonEventArgs e) { Debug.WriteLine(«GroupBox PreviewRightButtonDown»); } void GroupBoxRightButtonDown(object sender, MouseButtonEventArgs e) { Debug.WriteLine(«GroupBox RightButtonDown»); } void WindowPreviewRightButtonDown(object sender, MouseButtonEventArgs e) { Debug.WriteLine(«Window PreviewRightButtonDown»); } void WindowRightButtonDown(object sender, MouseButtonEventArgs e) { Debug.WriteLine(«Window RightButtonDown»); }

Во время работы этой программы события возникают в следующем порядке:

  1. Window PreviewMouseRightButtonDown.

  2. Window PreviewMouseRightButtonDown.

  3. GroupBox PreviewMouseRightButtonDown.

  4. Button PreviewMouseRightButtonDown.

  5. Button MouseRightButtonDown.

  6. GroupBox MouseRightButtonDown.

  7. Window MouseRightButtonDown.

Туннелирование и всплытие прекрасно работают для таких встроенных в каждый элемент управления событий, как события мыши. Однако туннелироваться и всплывать может любое событие. Чтобы обеспечить и туннелирование, и всплытие, WPF поддерживает присоединенные события. Подобно тому, как система свойств позволяет присоединять свойства к любому элементу, мы можем присоединить к любому элементу и обработчик событий.

Если мы хотим получать извещения о нажатии любой кнопки в окне, достаточно просто вызвать метод AddHandler. У каждого события в WPF имеется свойство типа RoutedEvent, которое во время исполнения ссылается на объект источник. Чтобы присоединить обработчик, мы передаем методу AddHandler объект RoutedEvent и делегат, который необходимо вызвать:

this.AddHandler(Button.ClickEvent, (RoutedEventHandler)delegate { MessageBox.Show(«Clicked»); });

WPF расширяет базовую модель событий .NET, добавляя систему маршрутизации событий, которая учитывает композицию элементов. Все остальные средства обработки действий построены на базе этой модели маршрутизации.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]