WPF learning notes routing events

Source: Internet
Author: User

1. messages that can be passed: the wpf ui is a tree structure consisting of layout and controls. When an event is triggered by a node on the tree, programmers can choose to use the traditional direct Event Mode to respond to the event, or let the event be transmitted in a certain direction in the UI component tree and pass through multiple transit nodes, and make the routing process properly processed.

2. WPF has two trees: Logical Tree and Visual tree. On the LogicTree, controls act as leaves. If we put the WPF controls under the magnifier ", you will find that each WPF space is also a tree composed of more subtle components. The magnifier used to observe the WPF control is the Blend we mentioned. If we derive the Logical Tree to the Template component level, we get the Visual Tree.

3. Route events are transmitted along the Visual Tree.

4. An event includes five aspects:

    1. Event owner
    2. Event
    3. Event Responder
    4. Event Processor
    5. Subscription relationship

5. Routing event principle: discard the direct event responder and turn different controls into listeners. The event owner is only responsible for the departure event.

6. Use the built-in routing event of WPF:

Most events in the Wpf system are routable events. We use the Click Event of the Button to describe how to use the routing event.

1. How to add listeners:

This. gridRoot. AddHandler (Button. ClickEvent, new RoutedEventHandler (DefineMethod ));

The above AddHandler method comes from the URElement class. The first parameter is Button. ClickEvent, which is called a routing event. Here we also use a method similar to the dependency attribute wrapper.

Note that in the routing event method, RoutedEventHandler. Source is gridRoot. If you want to get the Button, use RoutedEventHandler. OrigenalSource.

You can use the simplified method in Xaml: <Grid X: Name = "gridRoot" BackGround = "Lime" Button. Click = "ButtonClicked">

7. Custom route events

Three steps:

  1. Declare and register a route event
  2. Add CLR event packaging for routing events
  3. How to Create a route event

Check Code:

Public abstract class ButtonBase: ContentControl, ICommandSource {public static readonly RoutedEvent ClickEvent =/* register a route event */EventManager. registerRoutedEvent ("Click", RoutingStrategy. bubble, typeof (RoutedEventHandler), typeof (ButtonBase); public event RoutedEventHandler Click {add {this. addHandler (ClickEvent, value)} Remove {this. removeHandler (ClickEvent, value)} protected virtual void OnClick () {RoutedEventArgs newEvent = new RoutedEventArgs (ButtonBase. clickEvent, this); this. raiseEVent (newEvent );}}

Routing Policy:

  1. Bubble Up
  2. Tunnel Down
  3. Direct simulates CLR Direct events

Demo 2: implement a TimeButton class inherited from the Button and add a route event

// Create a RoutedEventArgs class: class ReportTimeEventArgs: RoutedEventArgs {Public ReportTimeEventArgs (RoutedEvent routedEvent, object source): Base (routedEvent, source) {} Public DateTime ClickTime {get; set ;}}
Class TimeButton: Button {// life and registration of a route event public static readonly RoutedEvent ReportTimeEvent = EventManager. registerRoutedEvent ("ReportTime", RoutingStrategy. bubble, typeof (EventHandler <ReportTimeEventArgs>), typeof (TimeButton); // CLR event packer public event RoutedEventhandler ReportTime {add {this. addHandler (ReportTimeEvent, value);} remove {this. removeHandler (ReportTimeEvent, value);} // triggers a route event. Borrow the Click Event excitation method protected override void OnClick () {base. onClick (); ReportTimeEventArgs args = new ReportTimeEventArgs (ReportTimeEvent, this); args. clickTime = DateTime. now; this. raiseEvent (args);} // Let's see how to use it.
       local:TimeButton.ReportTime = “ReportTimeHandler”;
// ReportTimeEvent route event Processor
           private void ReportTimeHandler(objecet sender, ReportTimeEventArgs e)
           {
                FrameworkElement element  = sender as FrameworkElement;
                string timeStr  = e.ClickTime.ToLongTimeString();
String content = string. Format ("{0} arrives at {1}", timeStr, element. Name );
                this.listBox.Items.Add(content);
           }
8. How to stop route events from spreading:
Use e. handled. If e. handled = true, the transfer is stopped.
9. RoutedEventArgs Source and OriginalSource
Source is the message Source of logicTree, while OriginalSource is the Source on visualTree.
If a Button is in UserControl, the Source should be UserControl, And the OriginalSource should be Button/
10. events are also appended-a simple introduction to additional events
Those classes have additional events
  • Binding class: SourceUpdated event and TargetUpdated event
  • Mouse: MouseEnter event, MouseLeave event, MouseDown event, and MouseUp event
  • Keyboard: KeyDown event and KeyUp event
Compared with routing events, the additional events are not displayed on the user interface.
Look at a Demo: design a Student class. If the Name attribute value of the Student instance changes, a routing event is triggered, and then the interface element is used to capture the event.
public class Student{    public static readonly RoutedEvent NameChangedEvent = EventManager.ResisterRoutedEvent      ( "NameChanged",routingStrategy.Bubble,typeof(RoutedEventHandler),typeof(Student));     public int Id {get;set;}     public string Name {get;set;}}
Then we design a button.
<Button  x:Name = "button1" Content="OK"  Width="80" Height="80"   Click="Button_Click">
Look at the background code
// Add an event listener
  this.gridMain.AddHandler(Student.nameChangedEvent, new RoutedEventHandler(this.DtudentnameChangedHandler))
// Click Event Processor
Private void Button_Click (objcet sender, RoutedEventArgs e) {Student stu = new Student () {Id = 10, Name = "Tim"}; stu. name = "Tom"; // prepare the event message and send the route event
// No route event can be sent when an event host is attached. You must use a FrameworkElement to RaiseEvent (arg)
// RoutedEventArgs has two parameters: an additional event and an instance. RoutedEventArgs arg = new RoutedEventArgs (Student. nameChangedEvent, stu); this. button1.RaiseEvent (arg);} // Grid captures the private void StudentNameChangedHandler (object sender, RoutedEventArgs e) {MessageBox. show (e. originalSource as Student ). id. toString ());}
11. The event is also appended with 2
In fact, the above example is already an additional file, but Microsoft's official documentation stipulates that a CLR package should be added for this additional event so that the XAML editor can identify and prompt only. However, because the Student class is not a derived class of UIElement and does not have the Addhandler and RemoveHandler methods, the CLR attribute cannot be used as the wrapper:
  • The packer that attaches an event listener to the target UI element is a public static method named Add * Handler. The asterisk represents the event name.
Public class Student {// declare and define the routing event public static readonly RoutedEvent NameChangedEvent = EventManager. registerRouredEvent ("NameChanged", RoutingStrategy. bubble, typeof (RoutedEventHandler), typdof (Student); // listen for public static void AddNameChangedHandler (DependencyObject d, RoutedEventHandler h) {UIElement e = d as UIElement; if (e! = Null) {e. AddHandler (Student. NameChangedEvent, h) ;}} public static voidRemoveNameChangedHandler (DependencyObject d, RoutedEventHandler h) {UIElement e = d as UIElement; if (e! = Null) {e. AddHandler (Student. NameChangedEvent, h) ;}} public int Id {get; set ;}public string Name {get; set ;}}

Public Window1 ()

{

Student. AddNameChangedHandler (this. gridMain, new RoutedEventHandler (this. StudnetnameChagnedHandler ));

}

Next, let's take a look at the additional events:

The UIElement class is the watershed between the routing event host and the additional event host, not only because the UIElemtn class has the ability to display on the interface, also, RaiseEvent, AddHandler, and RemoveHandler are defined in the UIElement class. If a route event is registered in a non-UIElement derived class, the instance of this class cannot activate or listen for this route event on its own.

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.