Så här skapar du en anpassad dirigerad händelse (WPF .NET)
Programutvecklare och komponentförfattare i Windows Presentation Foundation (WPF) kan skapa anpassade routade händelser för att utöka funktionerna i CLR-händelser (Common Language Runtime). Information om funktioner för routade händelser finns i Varför använda routade händelser. Den här artikeln beskriver grunderna för att skapa en anpassad dirigerad händelse.
Förutsättningar
Artikeln förutsätter grundläggande kunskaper om routade händelser och att du har läst Översikt över routade händelser. Om du vill följa exemplen i den här artikeln hjälper det om du är bekant med XAML (Extensible Application Markup Language) och vet hur du skriver WPF-program (Windows Presentation Foundation).
Steg för routad händelse
De grundläggande stegen för att skapa en dirigerad händelse är:
Registrera en RoutedEvent med hjälp av metoden RegisterRoutedEvent.
Registreringsanropet returnerar en
RoutedEvent
-instans, känd som en dirigerad händelseidentifierare, som innehåller det registrerade händelsenamnet, routningsstrategioch annan händelseinformation. Tilldela identifieraren till ett statiskt skrivskyddat fält. Enligt konvention:- Identifieraren för en dirigerad händelse med en bubblande strategi heter
<event name>Event
. Om händelsenamnet till exempel ärTap
ska identifieraren namngesTapEvent
. - Identifieraren för en dirigerad händelse med en -tunnel-strategi heter
Preview<event name>Event
. Om händelsenamnet till exempel ärTap
ska identifieraren namngesPreviewTapEvent
.
- Identifieraren för en dirigerad händelse med en bubblande strategi heter
Definiera CLR lägga till och ta bort händelseåtkomster. Utan CLR-händelseåtkomster kan du bara lägga till eller ta bort händelsehanterare via direkta anrop till metoderna UIElement.AddHandler och UIElement.RemoveHandler. Med CLR-händelseaccessorer får du tillgång till följande mekanismer för tilldelning av händelsehanterare:
- För XAML (Extensible Application Markup Language) kan du använda attributsyntax för att lägga till händelsehanterare.
- För C#kan du använda operatorerna
+=
och-=
för att lägga till eller ta bort händelsehanterare. - För VB kan du använda instruktionen AddHandler och RemoveHandler för att lägga till eller ta bort händelsehanterare.
Lägg till anpassad logik för att utlösa den dirigerade händelsen. Din logik kan till exempel utlösa händelsen baserat på användarindata och programtillstånd.
Exempel
I följande exempel implementeras klassen CustomButton
i ett anpassat kontrollbibliotek. Klassen CustomButton
, som härleds från Button:
- Registrerar en RoutedEvent med namnet
ConditionalClick
med hjälp av metoden RegisterRoutedEvent och anger strategin för bubblande vid registreringen. - Tilldelar instansen
RoutedEvent
, som returneras från registreringsanropet, till ett statiskt konstantfält med namnetConditionalClickEvent
. - Definierar CLR lägga till och ta bort händelseåtkomster.
- Lägger till anpassad logik för att utlösa den anpassade dirigerade händelsen när
CustomButton
klickas och ett externt villkor gäller. Även om exempelkoden genererar denConditionalClick
dirigerade händelsen från den åsidosattaOnClick
virtuella metoden, kan du utlösa händelsen på det sätt du vill.
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
Exemplet innehåller ett separat WPF-program som använder XAML-markering för att lägga till en instans av CustomButton
till en StackPaneloch för att tilldela metoden Handler_ConditionalClick
som ConditionalClick
händelsehanterare för elementen CustomButton
och StackPanel1
.
<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>
I code-behind definierar WPF-programmet den Handler_ConditionalClick
händelsehanterarmetoden. Händelsehanterarmetoder kan bara implementeras i 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.
När CustomButton
klickas:
- Den
ConditionalClick
dirigerade händelsen aktiveras påCustomButton
. - Den
Handler_ConditionalClick
händelsehanterare som är kopplad tillCustomButton
utlöses. - Den dirigerade händelsen
ConditionalClick
går upp i elementträdet tillStackPanel1
. - Den
Handler_ConditionalClick
händelsehanterare som är kopplad tillStackPanel1
utlöses. - Den
ConditionalClick
routade händelsen fortsätter upp i elementträdet och utlöser potentiellt andraConditionalClick
händelsehanterare som är kopplade till andra genomgångna element.
Händelsehanteraren för Handler_ConditionalClick
hämtar följande information om händelsen som utlöste den:
- Objektet avsändare, vilket är elementet som händelsehanteraren är kopplad till.
sender
kommer att varaCustomButton
första gången hanteraren körs, ochStackPanel1
andra gången. -
RoutedEventArgs.Source-objektet, vilket är det element som ursprungligen skapade händelsen. I det här exemplet är
Source
alltidCustomButton
.
Notis
En viktig skillnad mellan en dirigerad händelse och en CLR-händelse är att en dirigerad händelse passerar elementträdet och letar efter hanterare, medan en CLR-händelse inte passerar elementträdet och hanterare bara kan ansluta till källobjektet som skapade händelsen. Det innebär att en dirigerad händelse sender
kan vara vilket som helst genomgånget element i elementträdet.
Du kan skapa en tunnelhändelse på samma sätt som en bubblande händelse, förutom att du anger routningsstrategin i händelseregistreringsanropet till Tunnel. Mer information om tunnelhändelser finns i WPF-indatahändelser.
Se även
- översikt över routade händelser
- Indataöversikt
- översikt över Control-redigering
- Hantera en rutad händelse.
.NET Desktop feedback