Delen via


Een aangepaste gerouteerde gebeurtenis maken (WPF .NET)

Ontwikkelaars van WPF-toepassingen (Windows Presentation Foundation) en auteurs van onderdelen kunnen aangepaste gerouteerde gebeurtenissen maken om de functionaliteit van CLR-gebeurtenissen (Common Language Runtime) uit te breiden. Zie Waarom gerouteerde gebeurtenissengebruiken voor meer informatie over de mogelijkheden van gerouteerde gebeurtenissen. In dit artikel worden de basisbeginselen besproken van het maken van een aangepaste gebeurtenis met routering.

Voorwaarden

In het artikel wordt ervan uitgegaan dat u basiskennis hebt van gerouteerde gebeurtenissen en dat u overzicht van gerouteerde gebeurtenissen hebt gelezen. Als u de voorbeelden in dit artikel wilt volgen, helpt dit als u bekend bent met Extensible Application Markup Language (XAML) en weet hoe u WPF-toepassingen (Windows Presentation Foundation) schrijft.

Stappen voor gerouteerde gebeurtenissen

De basisstappen voor het maken van een gerouteerde gebeurtenis zijn:

  1. Registreer een RoutedEvent met behulp van de methode RegisterRoutedEvent.

  2. De registratieoproep retourneert een RoutedEvent exemplaar, ook wel een gerouteerde gebeurtenis-id genoemd, die de naam van de geregistreerde gebeurtenis bevat, routeringsstrategieen andere gebeurtenisdetails. Wijs de identificator toe aan een statisch alleen-lezen veld. Volgens conventie:

    • De identificatie voor een gerouteerde gebeurtenis met een -strategie heet <event name>Event. Als de gebeurtenisnaam bijvoorbeeld Tap is, dan moet de identificator TapEventworden genoemd.
    • De identificatie voor een gerouteerde gebeurtenis met een tunneling strategie heet Preview<event name>Event. Als de gebeurtenisnaam bijvoorbeeld Tap is, dan moet de identifier PreviewTapEventworden genoemd.
  3. Definieer CLR- toevoegen en gebeurtenistoegangsors verwijderen. Zonder CLR-gebeurtenistoegangsors kunt u alleen gebeurtenis-handlers toevoegen of verwijderen via directe aanroepen naar de UIElement.AddHandler en UIElement.RemoveHandler methoden. Met CLR-gebeurtenistoegangsaccessors krijgt u deze mechanismen voor gebeurtenishandlertoewijzing:

    • Voor Extensible Application Markup Language (XAML) kunt u de syntaxis van het kenmerk gebruiken om gebeurtenis-handlers toe te voegen.
    • Voor C# kunt u de operators += en -= gebruiken om gebeurtenis-handlers toe te voegen of te verwijderen.
    • Voor VB kunt u de AddHandler- en RemoveHandler-instructies gebruiken om gebeurtenis-handlers toe te voegen of te verwijderen.
  4. Voeg aangepaste logica toe voor het activeren van je gerouteerd evenement. Uw logica kan bijvoorbeeld de gebeurtenis activeren op basis van gebruikersinvoer en toepassingsstatus.

Voorbeeld

In het volgende voorbeeld wordt de CustomButton-klasse geïmplementeerd in een aangepaste besturingselementbibliotheek. De CustomButton klasse, die is afgeleid van Button:

  1. Registreert een RoutedEvent met de naam ConditionalClick met behulp van de methode RegisterRoutedEvent en geeft de strategie tijdens de registratie op.
  2. Hiermee wijst u het RoutedEvent exemplaar dat is geretourneerd door de registratieaanroep toe aan een statisch alleen-lezen veld met de naam ConditionalClickEvent.
  3. Definieert CLR-toevoegen en verwijderen voor gebeurtenistoegangsmethodes .
  4. Voegt aangepaste logica toe om de aangepaste gerouteerde gebeurtenis te genereren wanneer op de CustomButton wordt geklikt en een externe voorwaarde van toepassing is. Hoewel de voorbeeldcode de ConditionalClick gerouteerde gebeurtenis genereert vanuit de overschreven OnClick virtuele methode, kunt u uw gebeurtenis op elke gewenste manier genereren.
public class CustomButton : Button
{
    // Register a custom routed event using the Bubble routing strategy.
    public static readonly RoutedEvent ConditionalClickEvent = EventManager.RegisterRoutedEvent(
        name: "ConditionalClick",
        routingStrategy: RoutingStrategy.Bubble,
        handlerType: typeof(RoutedEventHandler),
        ownerType: typeof(CustomButton));

    // Provide CLR accessors for assigning an event handler.
    public event RoutedEventHandler ConditionalClick
    {
        add { AddHandler(ConditionalClickEvent, value); }
        remove { RemoveHandler(ConditionalClickEvent, value); }
    }

    void RaiseCustomRoutedEvent()
    {
        // Create a RoutedEventArgs instance.
        RoutedEventArgs routedEventArgs = new(routedEvent: ConditionalClickEvent);

        // Raise the event, which will bubble up through the element tree.
        RaiseEvent(routedEventArgs);
    }

    // For demo purposes, we use the Click event as a trigger.
    protected override void OnClick()
    {
        // Some condition combined with the Click event will trigger the ConditionalClick event.
        if (DateTime.Now > new DateTime())
            RaiseCustomRoutedEvent();

        // Call the base class OnClick() method so Click event subscribers are notified.
        base.OnClick();
    }
}
Public Class CustomButton
    Inherits Button

    ' Register a custom routed event with the Bubble routing strategy.
    Public Shared ReadOnly ConditionalClickEvent As RoutedEvent = EventManager.RegisterRoutedEvent(
        name:="ConditionalClick",
        routingStrategy:=RoutingStrategy.Bubble,
        handlerType:=GetType(RoutedEventHandler),
        ownerType:=GetType(CustomButton))

    ' Provide CLR accessors to support event handler assignment.
    Public Custom Event ConditionalClick As RoutedEventHandler

        AddHandler(value As RoutedEventHandler)
            [AddHandler](ConditionalClickEvent, value)
        End AddHandler

        RemoveHandler(value As RoutedEventHandler)
            [RemoveHandler](ConditionalClickEvent, value)
        End RemoveHandler

        RaiseEvent(sender As Object, e As RoutedEventArgs)
            [RaiseEvent](e)
        End RaiseEvent

    End Event

    Private Sub RaiseCustomRoutedEvent()

        ' Create a RoutedEventArgs instance.
        Dim routedEventArgs As New RoutedEventArgs(routedEvent:=ConditionalClickEvent)

        ' Raise the event, which will bubble up through the element tree.
        [RaiseEvent](routedEventArgs)

    End Sub

    ' For demo purposes, we use the Click event as a trigger.
    Protected Overrides Sub OnClick()

        ' Some condition combined with the Click event will trigger the ConditionalClick event.
        If Date.Now > New DateTime() Then RaiseCustomRoutedEvent()

        ' Call the base class OnClick() method so Click event subscribers are notified.
        MyBase.OnClick()

    End Sub
End Class

Het voorbeeld bevat een afzonderlijke WPF-toepassing die gebruikmaakt van XAML-markeringen om een exemplaar van de CustomButton toe te voegen aan een StackPanelen om de Handler_ConditionalClick methode toe te wijzen als de ConditionalClick gebeurtenishandler voor de CustomButton- en StackPanel1-elementen.

<Window x:Class="CodeSample.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:custom="clr-namespace:WpfControl;assembly=WpfControlLibrary"
        Title="How to create a custom routed event" Height="100" Width="300">

    <StackPanel Name="StackPanel1" custom:CustomButton.ConditionalClick="Handler_ConditionalClick">
        <custom:CustomButton
            Name="customButton"
            ConditionalClick="Handler_ConditionalClick"
            Content="Click to trigger a custom routed event"
            Background="LightGray">
        </custom:CustomButton>
    </StackPanel>
</Window>

De WPF-toepassing definieert in code-behind de event-handler methode voor Handler_ConditionalClick. Methoden voor gebeurtenis-handlers kunnen alleen worden geïmplementeerd in code-behind.

// The ConditionalClick event handler.
private void Handler_ConditionalClick(object sender, RoutedEventArgs e)
{
    string senderName = ((FrameworkElement)sender).Name;
    string sourceName = ((FrameworkElement)e.Source).Name;

    Debug.WriteLine($"Routed event handler attached to {senderName}, " +
        $"triggered by the ConditionalClick routed event raised on {sourceName}.");
}

// Debug output when CustomButton is clicked:
// Routed event handler attached to CustomButton,
//     triggered by the ConditionalClick routed event raised on CustomButton.
// Routed event handler attached to StackPanel1,
//     triggered by the ConditionalClick routed event raised on CustomButton.
' The ConditionalClick event handler.
Private Sub Handler_ConditionalClick(sender As Object, e As RoutedEventArgs)

    Dim sourceName As String = CType(e.Source, FrameworkElement).Name
    Dim senderName As String = CType(sender, FrameworkElement).Name

    Debug.WriteLine($"Routed event handler attached to {senderName}, " +
        $"triggered by the ConditionalClick routed event raised on {sourceName}.")

End Sub

' Debug output when CustomButton is clicked:
' Routed event handler attached to CustomButton,
'     triggered by the ConditionalClick routed event raised on CustomButton.
' Routed event handler attached to StackPanel1,
'     triggered by the ConditionalClick routed event raised on CustomButton.

Wanneer op CustomButton wordt geklikt:

  1. De ConditionalClick gerouteerde gebeurtenis wordt gegenereerd op CustomButton.
  2. De Handler_ConditionalClick gebeurtenis-handler die is gekoppeld aan CustomButton wordt geactiveerd.
  3. De ConditionalClick gerouteerde gebeurtenis beweegt omhoog in de elementstructuur tot StackPanel1.
  4. De Handler_ConditionalClick gebeurtenis-handler die is gekoppeld aan StackPanel1 wordt geactiveerd.
  5. De ConditionalClick gerouteerde gebeurtenis beweegt zich omhoog door de elementstructuur en kan daarbij mogelijk andere ConditionalClick gebeurtenis-handlers activeren die aan andere gepasseerde elementen zijn gekoppeld.

De Handler_ConditionalClick gebeurtenis-handler verkrijgt de volgende informatie over de gebeurtenis die deze heeft geactiveerd:

  • Het object sender is het element waaraan de gebeurtenis-handler is gekoppeld. De sender wordt CustomButton de eerste keer dat de handler wordt uitgevoerd en StackPanel1 de tweede keer.
  • Het RoutedEventArgs.Source-object, het element dat oorspronkelijk de gebeurtenis heeft gegenereerd. In dit voorbeeld is de Source altijd CustomButton.

Notitie

Een belangrijk verschil tussen een gerouteerde gebeurtenis en een CLR-gebeurtenis is dat een gerouteerde gebeurtenis de elementstructuur doorkruist, op zoek naar handlers, terwijl een CLR-gebeurtenis niet de elementstructuur doorkruist en handlers alleen kunnen worden gekoppeld aan het bronobject dat de gebeurtenis heeft gegenereerd. Als gevolg hiervan kan een gerouteerde gebeurtenis sender elk doorkruist element in de elementstructuur zijn.

U kunt een tunneling-gebeurtenis op dezelfde manier maken als een bubbling-gebeurtenis, behalve dat u de routeringsstrategie instelt in de oproep voor gebeurtenisregistratie op Tunnel. Zie WPF-invoer gebeurtenissenvoor meer informatie over tunnelingsevenementen.

Zie ook