Язык программирования C#9 и платформа .NET5
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.RoutedEventArgspublic void btnClickMe_Clicked(object sender, RoutedEventArgs e){<b> // Делать что-нибудь, когда на кнопке произведен щелчок.</b>MessageBox.Show("Clicked the button");}После запуска приложения окно сообщения будет отображаться независимо от того, на какой части содержимого кнопки был выполнен щелчок (зеленый элемент
, желтый элементEllipse, элементEllipseили поверхность элементаLabel). В принципе это хорошо. Только представьте, насколько громоздким оказалась бы обработка событий WPF, если бы пришлось обрабатывать событиеButtonдля каждого из упомянутых подэлементов. Дело не только в том, что создание отдельных обработчиков событий для каждого аспектаClick— трудоемкая задача, а еще и в том, что в результате получился бы сложный в сопровождении код.ButtonК счастью, маршрутизируемые события WPF позаботятся об автоматическом вызове единственного обработчика события
вне зависимости от того, на какой части кнопки был совершен щелчок. Выражаясь просто, модель маршрутизируемых событий автоматически распространяет событие вверх (или вниз) по дереву объектов в поисках подходящего обработчика.ClickТочнее говоря, маршрутизируемое событие может использовать три стратегии маршрутизации. Если событие перемещается от точки возникновения вверх к другим областям определений внутри дерева объектов, то его называют пузырьковым событием. И наоборот, если событие перемещается от самого внешнего элемента (например,
) вниз к точке возникновения, то его называют туннельным событием. Наконец, если событие инициируется и обрабатывается только элементом, внутри которого оно возникло (что можно было бы описать как нормальное событие CLR), то его называют прямым событием.WindowРоль пузырьковых маршрутизируемых событий
В текущем примере, когда пользователь щелкает на внутреннем овале желтого цвета, событие
поднимается на следующий уровень области определения (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" <b>MouseDown ="outerEllipse_MouseDown"</b>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>Затем реализуйте подходящий обработчик событий, который в демонстрационных целях будет просто изменять свойство
главного окна:Titlepublic void outerEllipse_MouseDown(object sender, MouseButtonEventArgs e){<b> // Изменить заголовок окна.</b>