Learning from WPF learning Events (II.)

Source: Internet
Author: User

  3.2 Custom Routed Events

In order to facilitate communication between objects in the program, we usually need to define some routed events ourselves. So how do you create custom routed events? The following example illustrates the creation of a custom routed event.

Creating a custom routed event is generally divided into three steps:

    1. Declaring and registering routed events

First, defining a routed event is very similar to the definition of a dependency property--Declaring a field of type RoutedEvent modified by public static ReadOnly, You then use the Registerroutedevent method of the EventManager class to register. The code for the complete registered routed event is as follows:

    1. Declares and registers a routed event public static readonly RoutedEvent clickevent = eventmanger.registerroutedevent ("click", Routingstrategy.bubble,typeof (Routedeventhandler), typeof (ButtonBase));

      Let's analyze the four parameters of the Eventmanger.registerroutedevent method.

      The first argument is of type string, which is called the name of the routed event. According to Microsoft's recommendation, the prefix of the string routedevent variable is consistent with the name of the CLR event wrapper. In this case, the name of the route variable is clickevent, and the string is click.

      The second parameter is a policy for routed events, in WPF, there are three strategies for routed events:

      • Bubble, bubbling: A routed event starts at the container that fires it, passing up the layer up to the outermost container (window or page).
      • Tunnel, tunnel: Routed events are passed in the same direction as bubble, which is moved by the root of the UI tree to the control that fires the event
      • Direct, Direct: simulates a CLR direct event, delivering the message directly to the event handler

      The third parameter is used to specify the type of the event handler. The event handler's return value type and parameter list must be consistent with the delegate specified by this parameter, or it will cause the compile-time exception to be thrown.

      The fourth parameter is used to indicate which type of host the routed event is.

    2. To create a CLR event wrapper for routed events

      Adding a CLR event wrapper for routed events is to expose routed events much like a traditional direct event, and without paying attention to the underlying implementation, the programmer will not feel the difference between it and the traditional direct event. In programming, you can still add event handlers for events using the + = number and use-= To remove event handlers that are no longer used.

    3. Create a method that can fire routed events

The way to fire a routed event is simple, first create a message that needs to be carried by the event and associate it with the routed event, and then call the element's RaiseEvent method to send the event.

Let's do it ourselves. A routed event is created that is used to report when an event occurs. This is an example of how custom routed events are created.

As mentioned above, there are three steps to creating a custom routed event, namely declaring and registering routed events, adding a wrapper for the CLR to routed events, and firing routed events. In this case, we want to fire the routed event, first to create a message that needs to be carried by the event. The so-called "no movement, fodder first", we start by creating an event parameter that is used to host the message.


1 //event arguments for hosting time messages2     classReporttimeeventargs:routedeventargs3     {4          PublicDateTime Clicktime {Get;Set; }5 6          PublicReporttimeeventargs (RoutedEvent routedevrent,ObjectSOURCE):Base(Routedevrent,source)7         {8 9         }Ten}

Then, create a derived class of the button class and add routed events for it as described in the previous steps:


1 classTimebutton:button2     {3         //declaring, registering routed events4          Public Static ReadOnlyRoutedEvent reporttimeevent = eventmanager.registerroutedevent ("Reporttime", Routingstrategy.bubble,typeof(eventhandler<reporttimeeventargs>),typeof(Timebutton));5 6         //CLR Event wrapper7          Public EventRoutedeventhandler Reporttime8         {9Add { This. AddHandler (reporttimeevent, value); }TenRemove { This. RemoveHandler (Reporttimeevent,value); } One         } A  -         //fires a routed event, borrowing the Click event's firing method -  the         protected Override voidOnClick () -         { -             Base. OnClick (); -  +Reporttimeeventargs args =NewReporttimeeventargs (Reporttimeevent, This); -Args. Clicktime =DateTime.Now; +              This. RaiseEvent (args); A         } at}

Here is the interface XAML code for the program:


1 <Windowx:class= "_02_ a custom routed 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 routed event"7 mc:ignorable= "D"8 Title= "Routed Event"Height= "+"Width= "+"Name= "Window_1"9 Local:TimeButton.ReportTime= "Reporttimehandle">Ten     <GridName= "Grid_1"Local:TimeButton.ReportTime= "Reporttimehandle"> One         <GridName= "Grid_2"Local:TimeButton.ReportTime= "Reporttimehandle"> A             <GridName= "Grid_3"Local:TimeButton.ReportTime= "Reporttimehandle"> -                 <StackPanelName= "Stackpanel_1"Local:TimeButton.ReportTime= "Reporttimehandle"> -                     <ListBoxName= "ListBox"Margin= "Ten"></ListBox> the                     <Local:timebuttonx:name= "Timebutton"Width= "a"Height= "a" - Content= "Chime"Local:TimeButton.ReportTime= "Reporttimehandle">                         -                     </Local:timebutton> -                 </StackPanel> +             </Grid> -         </Grid> +     </Grid> A </Window>

On the UI Interface, window is the root, with a three-layer grid and a layer of StackPanel (the Name property is set inside), Inside the innermost StackPanel is a listbox and Timebutton (the derived class of the button class just created above). We can see that from the outermost window to the most inner Timebutton, the listener reporttimeevent the routed event and responds to the event with the Reporttimehandle method. The code for Reporttimehandle is as follows:


1 //Reporttimeevent routed event handler2         Private voidReporttimehandle (Objectsender, Reporttimeeventargs e)3         {4FrameworkElement element = Sender asFrameworkElement;5             stringTimestr =e.clicktime.tolongtimestring ();6             stringContent =string. Format ("{0} reached {1}", timestr, element. Name);7              This. LISTBOX.ITEMS.ADD (content);9}

To run the program, the effect is as follows:

In this example, we use the policy of the routed event as bubbling (bubble), we make a simple modification to the program, when declaring and registering a routed event, change the policy of its event to tunnel (tunnel):


// declaring, registering routed events         Public Static ReadOnly RoutedEvent reporttimeevent = eventmanager.registerroutedevent ("reporttime"typeof  typeof(Timebutton));

The effect is as follows:


By comparing the two, we can clearly see that the two different strategies are different, so we can better understand what we said before.

At this point, you have a question, if you let a routed event be processed in a certain place, then no longer pass backwards? Very simply, in an instance of the RoutedEventArgs class or its derived class, it has a property of type bool handeled, and once this property is set to True, the routed event is no longer passed down. For our example, we need to make the following modifications:


1 //Reporttimeevent routed event handler2         Private voidReporttimehandle (Objectsender, Reporttimeeventargs e)3         {4FrameworkElement element = Sender asFrameworkElement;5             stringTimestr =e.clicktime.tolongtimestring ();6             stringContent =string. Format ("{0} reached {1}", timestr, element. Name);7              This. LISTBOX.ITEMS.ADD (content);8 9             if(element = = This. Grid_2)Ten             { Onee.handled =true; A             } -}

This is modified as follows:

    To be continue!


Learning from WPF learning Events (II.)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.