* Add article, toc, and redirects * Add a prerequisites section to 3 other event articles * Further edits * Update dotnet-desktop-guide/net/wpf/toc.yml Co-authored-by: Andy (Steve) De George <[email protected]> * Update article links * Minor clarification Co-authored-by: Andy (Steve) De George <[email protected]>
7.8 KiB
title, description, ms.date, dev_langs, helpviewer_keywords
| title | description | ms.date | dev_langs | helpviewer_keywords | ||||
|---|---|---|---|---|---|---|---|---|
| How to create a custom routed event | Learn how to implement a custom routed event for an element in Windows Presentation Foundation (WPF). | 02/02/2022 |
|
|
How to create a custom routed event (WPF .NET)
Windows Presentation Foundation (WPF) application developers and component authors can create custom routed events to extend the functionality of common language runtime (CLR) events. For information on routed event capabilities, see Why use routed events. This article covers the basics of creating a custom routed event.
[!INCLUDE desktop guide under construction]
Prerequisites
The article assumes a basic knowledge of routed events, and that you've read Routed events overview. To follow the examples in this article, it helps if you're familiar with Extensible Application Markup Language (XAML) and know how to write Windows Presentation Foundation (WPF) applications.
Routed event steps
The basic steps to create a routed event are:
-
Register a xref:System.Windows.RoutedEvent using the xref:System.Windows.EventManager.RegisterRoutedEvent%2A method.
-
The registration call returns a
RoutedEventinstance, known as a routed event identifier, which holds the registered event name, routing strategy, and other event details. Assign the identifier to a static readonly field. By convention:- The identifier for a routed event with a bubbling strategy is named
<event name>Event. For example, if the event name isTapthen the identifier should be namedTapEvent. - The identifier for a routed event with a tunneling strategy is named
Preview<event name>Event. For example, if the event name isTapthen the identifier should be namedPreviewTapEvent.
- The identifier for a routed event with a bubbling strategy is named
-
Define CLR add and remove event accessors. Without CLR event accessors, you'll only be able to add or remove event handlers through direct calls to the xref:System.Windows.UIElement.AddHandler%2A?displayProperty=nameWithType and xref:System.Windows.UIElement.RemoveHandler%2A?displayProperty=nameWithType methods. With CLR event accessors, you gain these event handler assignment mechanisms:
- For Extensible Application Markup Language (XAML), you can use attribute syntax to add event handlers.
- For C#, you can use the
+=and-=operators to add or remove event handlers. - For VB, you can use the AddHandler and RemoveHandler statements to add or remove event handlers.
-
Add custom logic for triggering your routed event. For example, your logic might trigger the event based on user-input and application state.
Example
The following example implements the CustomButton class in a custom control library. The CustomButton class, which derives from xref:System.Windows.Controls.Button:
- Registers a xref:System.Windows.RoutedEvent named
ConditionalClickusing the xref:System.Windows.EventManager.RegisterRoutedEvent%2A method, and specifies the bubbling strategy during registration. - Assigns the
RoutedEventinstance returned from the registration call to a static readonly field namedConditionalClickEvent. - Defines CLR add and remove event accessors.
- Adds custom logic to raise the custom routed event when the
CustomButtonis clicked and an external condition applies. Although the example code raises theConditionalClickrouted event from within the overriddenOnClickvirtual method, you can raise your event any way you choose.
:::code language="csharp" source="./snippets/how-to-create-a-custom-routed-event/WpfControlLibraryCsharp/CustomButton.cs" id="CustomButton"::: :::code language="vb" source="./snippets/how-to-create-a-custom-routed-event/WpfControlLibraryVb/CustomButton.vb" id="CustomButton":::
The example includes a separate WPF application that uses XAML markup to add an instance of the CustomButton to a xref:System.Windows.Controls.StackPanel, and to assign the Handler_ConditionalClick method as the ConditionalClick event handler for the CustomButton and StackPanel1 elements.
:::code language="xaml" source="./snippets/how-to-create-a-custom-routed-event/csharp/MainWindow.xaml" id="MainWindowXaml":::
In code-behind, the WPF application defines the Handler_ConditionalClick event handler method. Event handler methods can only be implemented in code-behind.
:::code language="csharp" source="./snippets/how-to-create-a-custom-routed-event/csharp/MainWindow.xaml.cs" id="EventHandler"::: :::code language="vb" source="./snippets/how-to-create-a-custom-routed-event/vb/MainWindow.xaml.vb" id="EventHandler":::
When CustomButton is clicked:
- The
ConditionalClickrouted event is raised onCustomButton. - The
Handler_ConditionalClickevent handler attached toCustomButtonis triggered. - The
ConditionalClickrouted event traverses up the element tree toStackPanel1. - The
Handler_ConditionalClickevent handler attached toStackPanel1is triggered. - The
ConditionalClickrouted event continues up the element tree potentially triggering otherConditionalClickevent handlers attached to other traversed elements.
The Handler_ConditionalClick event handler obtains the following information about the event that triggered it:
- The sender object, which is the element that the event handler is attached to. The
senderwill beCustomButtonthe first time the handler runs, andStackPanel1the second time. - The xref:System.Windows.RoutedEventArgs.Source?displayProperty=nameWithType object, which is the element that originally raised the event. In this example, the
Sourceis alwaysCustomButton.
Note
A key difference between a routed event and a CLR event is that a routed event traverses the element tree, looking for handlers, whereas a CLR event doesn't traverse the element tree and handlers can only attach to the source object that raised the event. As a result, a routed event
sendercan be any traversed element in the element tree.
You can create a tunneling event the same way as a bubbling event, except you'll set the routing strategy in the event registration call to xref:System.Windows.RoutingStrategy.Tunnel. For more information on tunneling events, see WPF input events.