Язык программирования C#9 и платформа .NET5
this.Title = "You clicked the outer ellipse!";}Далее можно выполнять разные действия в зависимости от того, на чем конкретно щелкнул конечный пользователь (на внешнем эллипсе или в любом другом месте внутри области кнопки).
На заметку! Пузырьковые маршрутизируемые события всегда перемещаются из точки возникновения до следующей определяющей области. Таким образом, в рассмотренном примере щелчок на элементе
привел бы к попаданию события в контейнерinnerEllipse, а не в элементCanvas, потому что оба элемента являются типамиouterEllipseвнутри области определенияEllipse.CanvasПродолжение или прекращение пузырькового распространения
В текущий момент, когда пользователь щелкает на объекте
, запускается зарегистрированный обработчик событияouterEllipseдля данного объектаMouseDown, после чего событие всплывет до событияEllipseкнопки. Чтобы информировать WPF о необходимости останова пузырькового распространения по дереву объектов, свойствоClickпараметраHandledпонадобится установить вMouseButtonEventArgs:truepublic void outerEllipse_MouseDown(object sender, MouseButtonEventArgs e){// Изменить заголовок окна.this.Title = "You clicked the outer ellipse!";// Остановить пузырьковое распространение.e.Handled = true;}В таком случае обнаружится, что заголовок окна изменился, но окно
, отображаемое обработчиком событияMessageBoxэлементаClick, не появляется. По существу пузырьковые маршрутизируемые события позволяют сложной группе содержимого действовать либо как единый логический элемент (например,Button), либо как отдельные элементы (скажем,ButtonвнутриEllipse).ButtonРоль туннельных маршрутизируемых событий
Строго говоря, маршрутизируемые события по своей природе могут быть пузырьковыми (как было описано только что) или туннельными. Туннельные события (имена которых начинаются с префикса
— наподобиеPreview) спускаются от самого верхнего элемента до внутренних областей определения дерева объектов. В общем и целом для каждого пузырькового события в библиотеках базовых классов WPF предусмотрено связанное туннельное событие, которое возникает перед его пузырьковым аналогом. Например, перед возникновением пузырькового событияPreviewMouseDownсначала инициируется туннельное событиеMouseDown.PreviewMouseDownОбработка туннельных событий выглядит очень похожей на обработку любых других событий: нужно просто указать имя обработчика события в разметке XAML (или при необходимости применить соответствующий синтаксис обработки событий C# в файле кода) и реализовать такой обработчик в коде. Для демонстрации взаимодействия туннельных и пузырьковых событий начните с организации обработки события
для объектаPreviewMouseDown:outerEllipse<Ellipse Name = "outerEllipse" Fill ="Green" Height ="25"MouseDown ="outerEllipse_MouseDown"PreviewMouseDown ="outerEllipse_PreviewMouseDown"Width ="50" Cursor="Hand" Canvas.Left="25" Canvas.Top="12"/>Затем модифицируйте текущее определение класса С#, обновив обработчики событий (для всех объектов) за счет добавления данных о событии в переменную-член
типа_mouseActivityс использованием входного объекта аргументов события. В результате появится возможность наблюдать за потоком событий, появляющихся в фоновом режиме.stringpublic partial class MainWindow : Window{string _mouseActivity = string.Empty;public MainWindow(){InitializeComponent();}public void btnClickMe_Clicked(object sender, RoutedEventArgs e){AddEventInfo(sender, e);MessageBox.Show(_mouseActivity, "Your Event Info");<b> // Очистить строку для следующего цикла.</b>_mouseActivity = "";}private void AddEventInfo(object sender, RoutedEventArgs e){_mouseActivity += string.Format("{0} sent a {1} event named {2}.\n", sender,e.RoutedEvent.RoutingStrategy,e.RoutedEvent.Name);}private void outerEllipse_MouseDown(object sender, MouseButtonEventArgs e){AddEventInfo(sender, e);}private void outerEllipse_PreviewMouseDown(object sender,MouseButtonEventArgs e){AddEventInfo(sender, e);}}