如何建立自訂路由事件 (WPF .NET)
Windows Presentation Foundation (WPF) 應用程式開發人員和元件作者可以建立自訂路由事件,以擴充 Common Language Runtime (CLR) 事件的功能。 如需路由事件功能的相關資訊,請參閱 為何使用路由事件 。 本文涵蓋建立自訂路由事件的基本概念。
重要
.NET 7 和 .NET 6 的桌面指南檔正在建置中。
必要條件
本文假設您已瞭解路由事件,而且您已閱讀 路由事件概觀 。 若要遵循本文中的範例,如果您熟悉可延伸的應用程式標記語言(XAML),並知道如何撰寫 Windows Presentation Foundation (WPF) 應用程式,它很有説明。
路由事件步驟
建立路由事件的基本步驟如下:
RoutedEvent使用 RegisterRoutedEvent 方法註冊 。
註冊呼叫會
RoutedEvent
傳回稱為路由事件識別碼的實例,此識別碼會保存已註冊的事件名稱、 路由策略 和其他事件詳細資料。 將識別碼指派給靜態唯讀欄位。 依照慣例:定義 CLR 新增 和 移除 事件存取子。 如果沒有 CLR 事件存取子,您就只能透過直接呼叫 UIElement.AddHandler 和 UIElement.RemoveHandler 方法來新增或移除事件處理常式。 使用 CLR 事件存取子時,您會取得下列事件處理常式指派機制:
- 針對 Extensible Application Markup Language (XAML),您可以使用屬性語法來新增事件處理常式。
- 針對 C#,您可以使用
+=
和-=
運算子來新增或移除事件處理常式。 - 針對 VB,您可以使用 AddHandler 和 RemoveHandler 語句來新增或移除事件處理常式。
新增自訂邏輯以觸發路由事件。 例如,您的邏輯可能會根據使用者輸入和應用程式狀態觸發事件。
範例
下列範例會在自訂控制項程式庫中實作 CustomButton
類別。 衍生自 Button 的 CustomButton
類別:
- RoutedEvent使用 RegisterRoutedEvent 方法註冊名為
ConditionalClick
的 ,並在註冊期間指定 反升 策略。 RoutedEvent
將從註冊呼叫傳回的實例指派給名為ConditionalClickEvent
的靜態唯讀欄位。- 定義 CLR 新增 和 移除 事件存取子。
- 新增自訂邏輯,以在按一下 時
CustomButton
引發自訂路由事件,並套用外部條件。 雖然範例程式碼會從覆寫OnClick
的虛擬方法內引發ConditionalClick
路由事件,但您可以以任何方式引發事件。
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
此範例包含使用 XAML 標記將 實例 CustomButton
加入 至 StackPanel 的個別 WPF 應用程式,以及將 方法指派 Handler_ConditionalClick
為 ConditionalClick
和 StackPanel1
專案的事件處理常式 CustomButton
。
<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>
在程式碼後置中,WPF 應用程式會 Handler_ConditionalClick
定義事件處理常式方法。 事件處理常式方法只能在程式碼後置中實作。
// 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.
按一下時 CustomButton
:
- 路由
ConditionalClick
事件會在 上CustomButton
引發。 - 附加至
CustomButton
的Handler_ConditionalClick
事件處理常式會觸發。 - 路由
ConditionalClick
事件會將專案樹狀結構周遊至StackPanel1
。 - 附加至
StackPanel1
的Handler_ConditionalClick
事件處理常式會觸發。 - 路由事件會
ConditionalClick
繼續向上移動,元素樹狀結構可能會觸發附加至其他周遊元素的其他ConditionalClick
事件處理常式。
Handler_ConditionalClick
事件處理常式會取得下列觸發事件的相關資訊:
- sender 物件,這是事件處理常式所附加的專案。 將是
sender
CustomButton
處理常式第一次執行,第StackPanel1
二次。 - 物件 RoutedEventArgs.Source ,這是原本引發事件的專案。 在此範例中,一
Source
律CustomButton
為 。
注意
路由事件與 CLR 事件之間的主要差異在於路由事件會周遊專案樹狀結構,尋找處理常式,而 CLR 事件不會周遊專案樹狀結構,而且處理常式只能附加至引發事件的來源物件。 因此,路由事件 sender
可以是專案樹狀結構中的任何周遊專案。
您可以建立通道事件的方式與反升事件相同,不同之處在于您會在事件註冊呼叫 Tunnel 中設定路由策略。 如需通道事件的詳細資訊,請參閱 WPF 輸入事件 。
另請參閱
意見反應
https://aka.ms/ContentUserFeedback。
即將登場:在 2024 年,我們將逐步淘汰 GitHub 問題作為內容的意見反應機制,並將它取代為新的意見反應系統。 如需詳細資訊,請參閱:提交並檢視相關的意見反應