WPF learning path (4) routing, wpf learning path routing
Routing event Overview
Function Definition: A routing event is an event that calls a handler for multiple listeners in the element tree, rather than for the objects that trigger the event.
Implementation Definition: A routing event is a CLR event that can be supported by RouteEvent instances and handled by the Windows Presentation Foundation (WPF) Event System.
Instance:
Xaml
<Border Height="50" Width="300" BorderBrush="Gray" BorderThickness="1"> <StackPanel Background="LightGray" Orientation="Horizontal" Button.Click="CommonClickHandler"> <Button Name="YesButton" Width="Auto" >Yes</Button> <Button Name="NoButton" Width="Auto" >No</Button> <Button Name="CancelButton" Width="Auto" >Cancel</Button> </StackPanel></Border>
In this simplified element tree, the Click Event source is a Button element, and the clicked Button is the first element that has the opportunity to process the event. However, if any handler appended to the Button does not apply to the event, the event will bubble up to the Button parent level (StackPanel) in the element tree ). This event may bubble to Border and then reach the page root of the element tree (not displayed ).
In other words, the event route for this Click event is: Button --> StackPanel --> Border -->...
Routing Event Policy
Bubbling: the routing event is then routed to the subsequent parent element until it reaches the root of the element tree.
Direct: only the source element has the opportunity to call the handler for response.
Tunneling: The event handler is initially called at the root of the element tree.
The routing Event Policy is changed due to the following factors:
Event processing functions
Public delegate void RoutedEventHandler (Object Sender, RoutedEventArgs e );
Public delegate void MouseEventHandler (Object Sender, MouseEventArgs e );
RoutedEventArgs and MouseEventArgs contain information about routing events.
If the "Handled" attribute is set to True, the routing event stops being transmitted.
Class and instance event processing functions
There are two types of event processing functions: the former is a common event processing function, the "instance event processing function", and the other is through EventManager. the RegisterClassHandler method associates an event handler function with a class, which has a higher priority.
Example: (from "sunflower collection-WPF manual" 6.5)
Custom Button class
public class MySimpleButton : Button{ static MySimpleButton() { EventManager.RegisterClassHandler(typeof(MySimpleButton), CustomClickEvent, new RoutedEventHandler(CustomClickClassHandler), false); } public event EventHandler ClassHandlerProcessed; public static void CustomClickClassHandler(Object sender, RoutedEventArgs e) { MySimpleButton simpBtn = sender as MySimpleButton; EventArgs args = new EventArgs(); simpBtn.ClassHandlerProcessed(simpBtn, e); } //Create and register routed event, routing strategies: Bubble public static readonly RoutedEvent CustomClickEvent = EventManager.RegisterRoutedEvent( "CustomClick", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(MySimpleButton)); //CLR event wrapper public event RoutedEventHandler CustomClick { add { AddHandler(CustomClickEvent, value); } remove { RemoveHandler(CustomClickEvent, value); } } //Raise CustomClickEvent void RaiseCustomClickEvent() { RoutedEventArgs newEventArgs = new RoutedEventArgs(MySimpleButton.CustomClickEvent); RaiseEvent(newEventArgs); } //Onclick protected override void OnClick() { RaiseCustomClickEvent(); }}
MainWindow. xaml
<Window x:Class="Alex_WPFAPPDemo02.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:custom="clr-namespace:Alex_WPFAPPDemo02" custom:MySimpleButton.CustomClick="InsertList" Title="MainWindow" Height="350" Width="525"> <Grid Margin="3" custom:MySimpleButton.CustomClick="InsertList" Name="Grid1"> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> <RowDefinition Height="Auto" /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <custom:MySimpleButton x:Name="simpBtn" CustomClick="InsertList"> My Simple Button </custom:MySimpleButton> <ListBox Margin="5" Name="listBox" Grid.Row="1" /> <CheckBox Margin="5" Grid.Row="2" Name="chkHandle"> Handle first event </CheckBox> <Button Grid.Row="3" HorizontalAlignment="Right" Margin="5" Padding="3" Click="clear"> Clear List </Button> </Grid></Window>
MainWindow. xaml. cs
protected int eventCounter = 0;private void InsertList(object sender, RoutedEventArgs e){ eventCounter++; string message = "#" + eventCounter.ToString() + ":\r\n" + "InsertList\r\n" + " Sender: " + sender.ToString() + "\r\n" + " Source: " + e.Source + "\r\n" + "Original Source: " + e.OriginalSource; listBox.Items.Add(message); e.Handled = (bool)chkHandle.IsChecked;}private void clear(object sender, RoutedEventArgs e){ eventCounter = 0; listBox.Items.Clear();}
Add class processing functions
static MySimpleButton(){ EventManager.RegisterClassHandler(typeof(MySimpleButton), CustomClickEvent, new RoutedEventHandler(CustomClickClassHandler), false);}public event EventHandler ClassHandlerProcessed;public static void CustomClickClassHandler(Object sender, RoutedEventArgs e){ MySimpleButton simpBtn = sender as MySimpleButton; EventArgs args = new EventArgs(); simpBtn.ClassHandlerProcessed(simpBtn, e);}
Complete code
public MainWindow(){ InitializeComponent(); this.simpBtn.ClassHandlerProcessed += new EventHandler(ButtonRaisedClass);}private void ButtonRaisedClass(object sender, EventArgs e){ eventCounter++; string message = "#" + eventCounter.ToString() + ":\r\n" + "Windows Class Handler\r\n" + " Sender: " + sender.ToString(); listBox.Items.Add(message);}private void ProcessHanldersToo(Object sender, RoutedEventArgs e){ eventCounter++; string message = "#" + eventCounter.ToString() + ":\r\n" + "ProcessHanldersToo\r\n" + " Sender: " + sender.ToString() + " Source: " + e.Source + "\r\n" + "Original Source: " + e.OriginalSource; listBox.Items.Add(message);}private void Window_Loaded(object sender, RoutedEventArgs e){ Grid1.AddHandler(MySimpleButton.CustomClickEvent, new RoutedEventHandler(ProcessHanldersToo), true);}
You can view the route of a route event.
To be continue...