Event learning in WPF (2) event Learning in wpf
3.2 custom route events
To facilitate communication between objects in the program, we usually need to define some routing events by ourselves. So how to create a custom routing event? The following example shows how to create a custom route event.
Generally, creating a custom route event consists of three steps:
First, the method for defining routing events and dependency properties is very similar-declaring a RoutedEvent type field modified by public static readonly, and then using the RegisterRoutedEvent method of the EventManager class for registration. The complete code for registering a route event is as follows:
The method to stimulate a routing event is very simple. First, create a message that requires the event to be carried and associate it with the routing event. Then, call the RaiseEvent method of the element to send the event.
Next, we create a routing event by ourselves. This event is used to report the event occurrence time. This example describes how to create a custom route event.
As mentioned above, creating a custom route event involves three steps: declaring and registering a route event, adding a CLR package for a route event, and initiating a route event. In this example, we need to create a message to be carried by the event to activate the routing event. As the saying goes, "don't change, grain and grass first", we first create an event parameter to carry messages.
1 // event parameter 2 class ReportTimeEventArgs: RoutedEventArgs 3 {4 public DateTime ClickTime {get; set;} 5 6 public ReportTimeEventArgs (RoutedEvent routedEvrent, object source ): base (routedEvrent, source) 7 {8 9} 10}
Then, create a derived class of the Button class and add a route event for it according to the preceding steps:
1 class TimeButton: Button 2 {3 // declare and register a route event 4 public static readonly RoutedEvent ReportTimeEvent = EventManager. registerRoutedEvent ("ReportTime", RoutingStrategy. bubble, typeof (EventHandler <ReportTimeEventArgs>), typeof (TimeButton); 5 6 // CLR event packer 7 public event RoutedEventHandler ReportTime 8 {9 add {this. addHandler (ReportTimeEvent, value);} 10 remove {this. removeHandler (ReportTimeEvent, value);} 11} 12 13 // use the Click Event excitation method 14 15 protected override void OnClick () 16 {17 base. onClick (); 18 19 ReportTimeEventArgs args = new ReportTimeEventArgs (ReportTimeEvent, this); 20 args. clickTime = DateTime. now; 21 this. raiseEvent (args); 22} 23}
The following is the program's interface XAML code:
1 <Window x: Class = "_ 02 _ custom routing event. MainWindow" 2 xmlns =" http://schemas.microsoft.com/winfx/2006/xaml /Presentation "3 xmlns: x =" http://schemas.microsoft.com/winfx/2006/xaml "4 xmlns: d =" http://schemas.microsoft.com/expression/blend/2008 "5 xmlns: mc =" http://schemas.openxmlformats.org/markup-compatibility/2006 "6 xmlns: local =" clr-namespace: _ 02 _ custom routing event "7 mc: ignorable = "d" 8 Title = "Routed Event" Height = "300" Width = "300" Name = "window_1" 9 local: TimeButton. reportTime = "ReportTimeHandle"> 10 <Grid Name = "grid_1" local: TimeButton. reportTime = "ReportTimeHandle"> 11 <Grid Name = "grid_2" local: TimeButton. reportTime = "ReportTimeHandle"> 12 <Grid Name = "grid_3" local: TimeButton. reportTime = "ReportTimeHandle"> 13 <StackPanel Name = "stackPanel_1" local: TimeButton. reportTime = "ReportTimeHandle"> 14 <ListBox Name = "listBox" Margin = "10"> </ListBox> 15 <local: TimeButton x: name = "timeButton" Width = "80" Height = "80" 16 Content = "reporting" local: TimeButton. reportTime = "ReportTimeHandle"> 17 </local: TimeButton> 18 </StackPanel> 19 </Grid> 20 </Grid> 21 </Grid> 22 </Window>
On the UI, the Window is used as the root, and a layer-3 Grid and a layer StackPanel are set (the Name attribute is set in it ), A ListBox and TimeButton (derived class of the Button class just created above) are placed in the innermost StackPanel ). We can see that from the Window on the outermost layer to the TimeButton on the innermost layer, the route event ReportTimeEvent is monitored and the ReportTimeHandle method is used to respond to the event. The ReportTimeHandle code is as follows:
1 // ReportTimeEvent routing event Processor 2 private void ReportTimeHandle (object sender, ReportTimeEventArgs e) 3 {4 FrameworkElement element = sender as FrameworkElement; 5 string timeStr = e. clickTime. toLongTimeString (); 6 string content = string. format ("{0} reaches {1}", timeStr, element. name); 7 this. listBox. items. add (content); 9}
Run the program, as shown in the following figure:
In this example, the routing Event Policy we use is bubble. We make a simple modification to the program. When declaring and registering a routing event, change the Event Policy to tunnel ):
// Declare and register the route event public static readonly RoutedEvent ReportTimeEvent = EventManager. RegisterRoutedEvent ("ReportTime", RoutingStrategy. Tunnel, typeof (EventHandler <ReportTimeEventArgs>), typeof (TimeButton ));
Shows the effect:
By comparing the two, we can clearly see that the two different strategies bring different results, so that we can better understand what we have mentioned earlier.
At this time, you may have a question: what if a route event is not passed back after it is processed somewhere? It is very simple. In the RoutedEventArgs class or its derived class instance, it has a bool type attribute Handeled. Once this attribute is set to true, the routing event will no longer be transmitted. Corresponding to our example, you need to make the following changes:
1 // ReportTimeEvent routing event Processor 2 private void ReportTimeHandle (object sender, ReportTimeEventArgs e) 3 {4 FrameworkElement element = sender as FrameworkElement; 5 string timeStr = e. clickTime. toLongTimeString (); 6 string content = string. format ("{0} reaches {1}", timeStr, element. name); 7 this. listBox. items. add (content); 8 9 if (element = this. grid_2) 10 {11 e. handled = true; 12} 13}
The modified result is as follows:
To Be Continue!