Чтение онлайн

на главную - закладки

Жанры

Язык программирования C#9 и платформа .NET5
Шрифт:

<Window ...

<Grid>

<Button Name="btnClickMe" Height="75" Width = "250"

Click ="btnClickMe_Clicked">

<StackPanel Orientation ="Horizontal">

<Label Height="50" FontSize ="20">

Fancy Button!</Label>

<Canvas Height ="50" Width ="100" >

<Ellipse Name = "outerEllipse" Fill ="Green"

Height ="25" Width ="50" Cursor="Hand"

Canvas.Left="25" Canvas.Top="12"/>

<Ellipse Name = "innerEllipse" Fill ="Yellow"

Height = "15" Width ="36"

Canvas.Top="17" Canvas.Left="32"/>

</Canvas>

</StackPanel>

</Button>

</Grid>

</Window>

Обратите

внимание, что в открывающем определении элемента
Button
было обработано событие
Click
за счет указания имени метода, который должен вызываться при возникновении события. Событие
Click
работает с делегатом
RoutedEventHandler
, который ожидает обработчик события, принимающий
object
в первом параметре и
System.Winodws.RoutedEventArgs
во втором. Реализуйте такой обработчик:

public void btnClickMe_Clicked(object sender, RoutedEventArgs e)

{

// Делать что-нибудь, когда на кнопке произведен щелчок.

MessageBox.Show("Clicked the button");

}

После запуска приложения окно сообщения будет отображаться независимо от того, на какой части содержимого кнопки был выполнен щелчок (зеленый элемент

Ellipse
, желтый элемент
Ellipse
, элемент
Label
или поверхность элемента
Button
). В принципе это хорошо. Только представьте, насколько громоздким оказалась бы обработка событий WPF, если бы пришлось обрабатывать событие
Click
для каждого из упомянутых подэлементов. Дело не только в том, что создание отдельных обработчиков событий для каждого аспекта
Button
— трудоемкая задача, а еще и в том, что в результате получился бы сложный в сопровождении код.

К счастью, маршрутизируемые события WPF позаботятся об автоматическом вызове единственного обработчика события

Click
вне зависимости от того, на какой части кнопки был совершен щелчок. Выражаясь просто, модель маршрутизируемых событий автоматически распространяет событие вверх (или вниз) по дереву объектов в поисках подходящего обработчика.

Точнее говоря, маршрутизируемое событие может использовать три стратегии маршрутизации. Если событие перемещается от точки возникновения вверх к другим областям определений внутри дерева объектов, то его называют пузырьковым событием. И наоборот, если событие перемещается от самого внешнего элемента (например,

Window
) вниз к точке возникновения, то его называют туннельным событием. Наконец, если событие инициируется и обрабатывается только элементом, внутри которого оно возникло (что можно было бы описать как нормальное событие CLR), то его называют прямым событием.

Роль пузырьковых маршрутизируемых

событий

В текущем примере, когда пользователь щелкает на внутреннем овале желтого цвета, событие

Click
поднимается на следующий уровень области определения (
Canvas
), затем на
StackPanel
и в итоге на уровень
Button
, где обрабатывается. Подобным же образом, если пользователь щелкает на
Label
, то событие всплывает на уровень
StackPanel
и, в конце концов, попадает в элемент
Button
.

Благодаря такому шаблону пузырьковых маршрутизируемых событий не придется беспокоиться о регистрации специфичных обработчиков события

Click
для всех членов составного элемента управления. Однако если необходимо выполнить специальную логику обработки щелчков для нескольких элементов внутри того же самого дерева объектов, то это вполне можно делать.

В целях иллюстрации предположим, что щелчок на элементе управления

outerEllipse
должен быть обработан в уникальной манере. Сначала обработайте событие
MouseDown
для этого подэлемента (графически визуализируемые типы вроде
Ellipse
не поддерживают событие
Click
, но могут отслеживать действия кнопки мыши через события
MouseDown
,
MouseUp
и т.д.):

<Button Name="btnClickMe" Height="75" Width = "250"

Click ="btnClickMe_Clicked">

<StackPanel Orientation ="Horizontal">

<Label Height="50" FontSize ="20">Fancy Button!</Label>

<Canvas Height ="50" Width ="100" >

<Ellipse Name = "outerEllipse" Fill ="Green"

Height ="25" MouseDown ="outerEllipse_MouseDown"

Width ="50" Cursor="Hand" Canvas.Left="25" Canvas.Top="12"/>

<Ellipse Name = "innerEllipse" Fill ="Yellow" Height = "15" Width ="36"

Canvas.Top="17" Canvas.Left="32"/>

</Canvas>

</StackPanel>

</Button>

Затем реализуйте подходящий обработчик событий, который в демонстрационных целях будет просто изменять свойство

Title
главного окна:

public void outerEllipse_MouseDown(object sender, MouseButtonEventArgs e)

{

// Изменить заголовок окна.

this.Title = "You clicked the outer ellipse!";

}

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

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

innerEllipse
привел бы к попаданию события в контейнер
Canvas
, а не в элемент
outerEllipse
, потому что оба элемента являются типами
Ellipse
внутри области определения
Canvas
.

Поделиться:
Популярные книги

СД. Восемнадцатый том. Часть 1

Клеванский Кирилл Сергеевич
31. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
6.93
рейтинг книги
СД. Восемнадцатый том. Часть 1

Вторая невеста Драконьего Лорда. Дилогия

Огненная Любовь
Вторая невеста Драконьего Лорда
Любовные романы:
любовно-фантастические романы
5.60
рейтинг книги
Вторая невеста Драконьего Лорда. Дилогия

Вечная Война. Книга VII

Винокуров Юрий
7. Вечная Война
Фантастика:
юмористическая фантастика
космическая фантастика
5.75
рейтинг книги
Вечная Война. Книга VII

Темный Патриарх Светлого Рода 6

Лисицин Евгений
6. Темный Патриарх Светлого Рода
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Темный Патриарх Светлого Рода 6

Не верь мне

Рам Янка
7. Самбисты
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Не верь мне

Неудержимый. Книга III

Боярский Андрей
3. Неудержимый
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Неудержимый. Книга III

LIVE-RPG. Эволюция-1

Кронос Александр
1. Эволюция. Live-RPG
Фантастика:
социально-философская фантастика
героическая фантастика
киберпанк
7.06
рейтинг книги
LIVE-RPG. Эволюция-1

Колючка для высшего эльфа или сиротка в академии

Жарова Анита
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Колючка для высшего эльфа или сиротка в академии

Адский пекарь

Дрейк Сириус
1. Дорогой пекарь!
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Адский пекарь

Я до сих пор не князь. Книга XVI

Дрейк Сириус
16. Дорогой барон!
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я до сих пор не князь. Книга XVI

Огненный князь

Машуков Тимур
1. Багряный восход
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Огненный князь

Царь поневоле. Том 1

Распопов Дмитрий Викторович
4. Фараон
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Царь поневоле. Том 1

Конструктор

Семин Никита
1. Переломный век
Фантастика:
попаданцы
альтернативная история
4.50
рейтинг книги
Конструктор

Сильнейший ученик. Том 2

Ткачев Андрей Юрьевич
2. Пробуждение крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сильнейший ученик. Том 2