事件與路由事件概觀

重要 API

我們描述了使用 C#、Visual Basic 或 Visual C++ 元件延伸模組 (C++/CX) 做為程式語言,並使用 XAML 做為 UI 定義時 Windows 執行階段應用程式中事件的程式設計概念。 您可以將事件的處理常式指派為 XAML 中 UI 元素宣告的一部分,也可以在程式碼中新增處理常式。 Windows 執行階段支援路由事件:某些輸入事件和資料事件可由引發事件之物件以外的物件處理。 當您定義控制項範本或是使用頁面或配置容器時,路由事件非常實用。

事件做為程式設計概念

一般而言,在設計 Windows 執行階段應用程式時的事件概念與最受歡迎的程式設計語言的事件模型類似。 如果您已經知道如何使用 Microsoft .NET 或 C++ 事件,那麼您就已經領先了。 但是您不需要瞭解太多有關事件模型概念的知識來執行一些基本工作,例如附加處理常式。

當您使用 C#、Visual Basic 或 C++/CX 做為程式設計語言時,UI 會在標記中定義 (XAML)。 在 XAML 標記語法中,標記元素與執行階段程式碼實體之間連接事件的一些原則類似於其他 Web 技術,例如 ASP.NET 或 HTML5。

注意:提供 XAML 定義 UI 執行階段邏輯的程式碼通常稱為程式碼後置或程式碼後置檔案。 在 Microsoft Visual Studio 解決方案檢視中,此關聯性會以圖形方式顯示,程式碼後置檔案是相依和巢狀檔案,與所參考的 XAML 頁面。

Button.Click:事件和 XAML 簡介

Windows 執行階段應用程式最常見的程式設計工作之一是擷取使用者對 UI 的輸入。 例如,您的 UI 可能有使用者必須按一下以提交資訊或變更狀態的按鈕。

您可以藉由產生 XAML 來定義 Windows 執行階段應用程式的 UI。 此 XAML 通常是 Visual Studio 中設計介面的輸出。 您也可以在純文字編輯器或第三方 XAML 編輯器中撰寫 XAML。 產生該 XAML 時,您可以連接個別 UI 元素的事件處理常式,同時定義建立該 UI 元素屬性值的所有其他 XAML 屬性。

若要在 XAML 中連接事件,您可以指定您已定義或稍後在程式碼後置中定義之處理常式方法的字串形式名稱。 例如,此 XAML 會定義一個 Button 物件,並將其他屬性 (x:Name 屬性Content) 指定為屬性,並透過參考名為 ShowUpdatesButton_Click 的方法來連接按鈕的 Click 事件的處理常式:

<Button x:Name="showUpdatesButton"
  Content="{Binding ShowUpdatesText}"
  Click="ShowUpdatesButton_Click"/>

提示:事件連接是一個程式設計詞彙。 它會參考程序或程式碼,指出事件發生時應該叫用具名處理常式方法。 在大多數程序程式碼模型中,事件連接是隱含或明確的「AddHandler」程式碼,它命名事件和方法,並且通常涉及目標物件執行個體。 在 XAML 中,「AddHandler」是隱含的,而事件連接完全包含將事件命名為物件元素的屬性名稱,並將處理常式命名為該屬性的值。

您可以使用程式設計語言撰寫實際處理常式,以您用於所有應用程式的程式碼和程式碼後置。 使用屬性 Click="ShowUpdatesButton_Click",您建立了一份合約,當 XAML 進行標記編譯和剖析時,IDE 建置行動中的 XAML 標記編譯步驟和應用程式載入時的最終 XAML 剖析,都可以找到名為 ShowUpdatesButton_Click 的方法的一部分應用程式的程式碼。 ShowUpdatesButton_Click 必須是為 Click 事件的任何處理常式實作相容方法簽章 (以委派為基礎) 的方法。 例如,此程式碼會定義 ShowUpdatesButton_Click 處理常式。

private void ShowUpdatesButton_Click (object sender, RoutedEventArgs e) 
{
    Button b = sender as Button;
    //more logic to do here...
}
Private Sub ShowUpdatesButton_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
    Dim b As Button = CType(sender, Button)
    '  more logic to do here...
End Sub
void winrt::MyNamespace::implementation::BlankPage::ShowUpdatesButton_Click(Windows::Foundation::IInspectable const& sender, Windows::UI::Xaml::RoutedEventArgs const& e)
{
    auto b{ sender.as<Windows::UI::Xaml::Controls::Button>() };
    // More logic to do here.
}
void MyNamespace::BlankPage::ShowUpdatesButton_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e) 
{
    Button^ b = (Button^) sender;
    //more logic to do here...
}

在此範例中,此方法是以 ShowUpdatesButton_ClickRoutedEventHandler 委派為基礎。 您會知道這是要使用的委派,因為您將看到在 Click 方法的語法中命名的委派。

提示:Visual Studio 可讓您在編輯 XAML 時命名事件處理常式並定義處理常式方法。 當您在 XAML 文字編輯器中提供事件的屬性名稱時,請稍候片刻,直到 Microsoft IntelliSense 清單顯示為止。 如果您從清單中按一下 <[新增事件處理常式]>,Microsoft Visual Studio 會根據元素的 x:Name (或類型名稱)、事件名稱和數字尾碼來建議方法名稱。 然後,您可以在選取的事件處理常式名稱上按下滑鼠右鍵,然後按一下瀏覽至事件處理常式。 這會直接瀏覽至新插入的事件處理常式定義,如 XAML 頁面程式碼後置檔案的程式碼編輯器檢視中所見。 事件處理常式已經有正確的簽章,包括傳送者參數和事件所使用的事件資料類別。 此外,如果具有正確簽章的處理常式方法已存在於程式碼後置中,該方法的名稱會出現在自動完成下拉式清單中,以及 <[新增事件處理常式] >選項。 您也可以按 Tab 鍵做為快捷方式,而不是按一下 IntelliSense 清單項目。

定義事件處理常式

如果是 UI 元素且在 XAML 中宣告的物件,事件處理常式程式碼會定義在部分類別中,做為 XAML 頁面的程式碼後置。 事件處理常式是您在與 XAML 相關聯之部分類別中撰寫的方法。 這些事件處理常式是以特定事件所使用的委派為基礎。 您的事件處理常式方法可以是公用或私用的。 私用存取之所以有效,是因為 XAML 建立的處理常式和執行個體最終透過程式碼產生連接在一起。 一般而言,我們建議您在類別中將事件處理常式方法設為私用。

注意:C++ 的事件處理常式不會在部分類別中定義,它們會在標題中宣告為私用類別成員。 C++ 專案的建置動作會負責產生程式碼,以支援適用於 C++ 的 XAML 類型系統和程式碼後置模型。

傳送者參數和事件資料

您為事件編寫的處理常式可以存取兩個值,這兩個值可用做呼叫處理常式的每種案例的輸入。 第一個這樣的值是傳送者,它是對附加處理常式的物件的參考。 傳送者參數的類型為基底物件類型。 常見的技巧是將傳送者轉換成更精確的類型。 如果您預期要檢查或變更傳送者物件本身的狀態,這項技術會很有用。 根據您自己的應用程式設計,您通常知道根據附加處理常式或其他設計細節,安全地將傳送者轉換成的類型。

第二個值是事件資料,通常做為 e 參數出現在語法定義中。 您可以在 Visual Studio 中查看指派給所處理特定事件之委派的 e 參數,然後在 Visual Studio 中使用 IntelliSense 或物件瀏覽器,以探索哪些事件資料的屬性可供使用。 或者,您可以使用 Windows 執行階段參考文件。

對於某些事件,事件資料的特定屬性值與知道事件發生一樣重要。 這特別適用於輸入事件。 對於指標事件,事件發生時指標的位置可能很重要。 對於鍵盤事件,所有可能的按鍵按下都會引發 KeyDownKeyUp 事件。 若要判斷使用者按下哪一個按鍵,您必須存取事件處理常式可用的 KeyRoutedEventArgs。 如需處理輸入事件的詳細資訊,請參閱鍵盤互動處理指標輸入。 輸入事件和輸入案例通常有本主題未涵蓋的其他考慮,例如指標事件的指標擷取,以及鍵盤事件的輔助按鍵和平台按鍵碼。

使用非同步模式的事件處理常式

在某些情況下,您會想要使用在事件處理常式中使用非同步模式的 API。 例如,您可以使用 AppBar 中的 Button 來顯示檔案選擇器並與其互動。 不過,許多檔案選擇器 API 都是非同步的。 它們必須在非同步/可等候的範圍內呼叫,編譯程式將會強制執行此動作。 因此,您可以執行的動作是將 async 關鍵字新增至事件處理常式,讓處理常式現在是 asyncvoid。 現在,您的事件處理常式可以進行非同步/可等候的呼叫。

如需使用非同步模式處理使用者互動事件範例,請參閱檔案存取和選擇器 (使用 C# 或 Visual Basic 系列建立第一個 Windows 執行階段應用程式的一部分)。 另請參閱 [在 C 中呼叫非同步 API]。

在程式碼中新增事件處理常式

XAML 不是將事件處理常式指派給物件的唯一方法。 若要將事件處理常式新增至程式碼中的任何指定物件,包括無法用於 XAML 的物件,您可以使用語言特定的語法來新增事件處理常式。

在 C# 中,語法是使用 += 運算子。 您可以藉由參考運算子右側的事件處理常式方法名稱來註冊處理常式。

如果使用程式碼將事件處理常式新增至出現在執行階段 UI 中的物件,通常的做法是新增此類處理常式以回應物件生存期事件或回呼 (例如 LoadedOnApplyTemplate),以便相關物件已準備好在執行階段處理使用者啟動的事件。 此範例顯示頁面結構的 XAML 大綱,然後提供 C# 語言語法,以將事件處理常式新增至物件。

<Grid x:Name="LayoutRoot" Loaded="LayoutRoot_Loaded">
  <StackPanel>
    <TextBlock Name="textBlock1">Put the pointer over this text</TextBlock>
...
  </StackPanel>
</Grid>
void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
{
    textBlock1.PointerEntered += textBlock1_PointerEntered;
    textBlock1.PointerExited += textBlock1_PointerExited;
}

注意:有更詳細的語法存在。 在 2005 年,C# 新增了稱為委派推斷的功能,可讓編譯程式推斷新的委派執行個體,並啟用先前更簡單的語法。 詳細資訊語法的功能與上一個範例相同,但在註冊之前明確建立新的委派執行個體,因此不會利用委派推斷。 這個明確的語法較不常見,但在某些程式碼範例中,您仍會看到它。

void LayoutRoot_Loaded(object sender, RoutedEventArgs e)
{
    textBlock1.PointerEntered += new PointerEventHandler(textBlock1_PointerEntered);
    textBlock1.PointerExited += new MouseEventHandler(textBlock1_PointerExited);
}

Visual Basic 語法有兩種可能性。 其中一個是平行處理 C# 語法,並將處理常式直接附加至執行個體。 這需要 AddHandler 關鍵字,以及取值處理常式方法名稱的 AddressOf 運算子。

Visual Basic 語法的另一個選項是在事件處理常式上使用 Handles 關鍵字。 這項技術適用於預期處理常式在載入時存在於物件上,並在整個物件存留期記憶體保存的情況。 在 XAML 中定義的物件上使用控制代碼需要您提供 Name / x:Name。 此名稱會成為控制代碼語法之 Instance.Event 部分所需的執行個體限定詞。 在此情況下,您不需要以物件存留期為基礎的事件處理常式,來起始附加其他事件處理常式;當您編譯 XAML 頁面時,會建立控制代碼連接。

Private Sub textBlock1_PointerEntered(ByVal sender As Object, ByVal e As PointerRoutedEventArgs) Handles textBlock1.PointerEntered
' ...
End Sub

注意:Visual Studio 及其 XAML 設計介面通常會提升執行個體處理技術,而不是控制代碼關鍵字。 這是因為在 XAML 中建立事件處理常式連接是一般設計工具開發人員工作流程的一部分,而控制代碼關鍵字技術與在 XAML 中連接事件處理常式不相容。

在 C++/CX 中,您也會使用 += 語法,但與基本 C# 形式有不同:

  • 沒有任何委派推斷存在,因此您必須針對委派執行個體使用 ref new
  • 委派建構函式有兩個參數,而且需要目標物件做為第一個參數。 通常由您指定。
  • 委委派構函式需要方法位址做為第二個參數,因此 & 參考運算子位於方法名稱之前。
textBlock1().PointerEntered({this, &MainPage::TextBlock1_PointerEntered });
textBlock1->PointerEntered += 
ref new PointerEventHandler(this, &BlankPage::textBlock1_PointerEntered);

移除程式碼中的事件處理常式

您通常不需要移除程式碼中的事件處理常式,即使您在程式碼中新增它們也一樣。 大部分 Windows 執行階段物件的物件存留期行為,例如頁面和控制項會在與主視窗及其視覺化樹狀結構中斷連線時終結物件,而且任何委派參考也會終結。 .NET 會透過垃圾收集執行這項作業,並使用 C++/CX Windows 執行階段預設會使用弱式參考。

在某些情況下,您確實想要明確移除事件處理常式。 包括:

  • 您為靜態事件新增的處理常式,以傳統方式無法進行垃圾收集。 Windows 執行階段 API 中的靜態事件範例是 CompositionTarget剪貼簿類別的事件。
  • 測試程式碼,其中您希望處理常式移除的時機為立即,或是在執行階段交換舊/新事件處理常式的程式碼。
  • 自訂移除存取子的實作。
  • 自訂靜態事件。
  • 頁面導覽的處理常式。

FrameworkElement.UnloadedPage.NavigatedFrom 是可能的事件觸發程序,這些觸發程序在狀態管理和物件存留期中具有適當的位置,因此您可以使用它們來移除其他事件的處理常式。

例如,您可以使用此程式碼,從目標物件 textBlock1 移除名為 textBlock1_PointerEntered 的事件處理常式。

textBlock1.PointerEntered -= textBlock1_PointerEntered;
RemoveHandler textBlock1.PointerEntered, AddressOf textBlock1_PointerEntered

您也可以移除透過 XAML 屬性新增事件的處理常式,這表示處理常式是在產生的程式碼中新增。 如果您為附加處理常式元素提供了名稱值,這比較容易,因為之後會提供程式碼的物件參考;不過,您也可以逐步執行物件樹狀結構,以便在物件沒有名稱的情況下尋找必要的物件參考。

如果您需要移除 C++/CX 中的事件處理常式,您需要註冊權杖,且應該從事件處理常式註冊的 += 傳回值接收該權杖。 這是因為 C++/CX 語法中 -= 取消註冊右側使用的值是標記,而不是方法名稱。 針對 C++/CX,您無法移除新增為 XAML 屬性的處理常式,因為 C++/CX 產生的程式碼不會儲存權杖。

路由事件

使用 C#、Microsoft Visual Basic 或 C++/CX 的 Windows 執行階段支援路由事件的概念,適用於大部分 UI 元素上存在的一組事件。 這些事件適用於輸入和使用者互動案例,且會在 UIElement 基底類別上實作。 以下是路由事件的輸入事件清單:

路由事件是可能從下層物件傳遞 (路由) 到物件樹狀結構中其每個連續上層物件的事件。 UI 的 XAML 結構大約是這個樹狀結構,該樹狀結構的根目錄是 XAML 中的根元素。 true 物件樹狀結構可能會與 XAML 元素巢狀結構有些不同,因為物件樹狀結構不包含 XAML 語言功能,例如屬性元素標記。 您可以將路由事件想像為從觸發該事件的任何 XAML 物件元素下層元素,向包含該事件的上層物件元素的反昇。 事件及其事件資料可以在事件路由上的多個物件上處理。 如果沒有元素具有處理常式,路由可能會持續執行,直到到達根元素為止。

如果您知道動態 HTML (DHTML) 或 HTML5 等 Web 技術,您可能已經熟悉反昇事件概念。

當路由事件透過其事件路由反昇時,任何附加事件處理常式都會存取事件資料的共用執行個體。 因此,如果處理常式可寫入任何事件資料,則對事件資料所做的任何變更都會傳遞至下一個處理常式,而且可能不再代表事件的原始事件資料。 當事件具有路由事件行為時,參考文件會包含有關路由行為的備註或其他表示法。

RoutedEventArgsOriginalSource 屬性

當事件反昇事件路由時,傳送者不再是與事件引發物件相同的物件。 相反地,傳送者是附加所叫用處理常式的物件。

在某些情況下,傳送者並不有趣,而您感興趣的是資訊,例如觸發指標事件時指標位於哪些可能的下層物件上,或者當使用者按下鍵盤鍵時較大 UI 中的哪個物件保持焦點。 在這些情況下,您可以使用 OriginalSource 屬性的值。 在路由上的所有點,OriginalSource 會報告引發事件的原始物件,而不是附加處理常式的物件。 不過,對於 UIElement 輸入事件,該原始物件通常是頁面層級 UI 定義 XAML 中無法立即看到的物件。 相反地,原始來源物件可能是控制項的樣板化部分。 例如,如果使用者將指標暫留在 Button 的邊緣上,就大部分的指標事件而言,OriginalSourceTemplate 中的 Border 範本組件,而不是 Buttonx 本身。

提示:如果您要建立樣板化控制項,輸入事件反昇特別有用。 具有範本的任何控制項都可以由其取用者套用新的範本。 嘗試重新建立工作範本的取用者,可能會無意中排除預設範本中宣告的某些事件處理。 在類別定義中附加處理常式做為 OnApplyTemplate 覆寫的一部分,您仍然可以提供控制層級事件處理。 然後,您可以攔截在具現化時升至控制項根目錄的輸入事件。

已處理的屬性

特定路由事件的數個事件資料類別包含名為已處理的屬性。 例如,請參閱 PointerRoutedEventArgs.HandledKeyRoutedEventArgs.HandledDragEventArgs.Handled。 在所有情況下,,已處理的都是可設定的布林值屬性。

已處理的屬性設為 true 會影響事件系統行為。 當已處理的true 時,大多數事件處理常式的路由會停止;該事件不會繼續沿著該路線通知其他附加的處理常式該特定事件情況。 「已處理的」在事件內容中的意義,以及您的應用程式對您有何回應。 基本上,Handled 是一個簡單的通訊協定,可讓應用程式程式碼指出發生事件不需要反昇至任何容器,您的應用程式邏輯會負責完成哪些工作。 但相反,您必須小心,不要處理可能應該反昇的事件,以便內建系統或控制行為可以起作用。例如,處理選擇控制項的部分或項目內的低階事件可能是有害的。 選取控制項可能會尋找輸入事件,以瞭解選取範圍應該變更。

並非所有路由事件都可以透過這種方式取消路由,您可以看到這一點,因為它們沒有 Handled 屬性。 例如,GotFocusLostFocus 確實會反昇,但它們總是一直反昇到底,而且它們的事件資料類別沒有可以影響該行為的 Handled 屬性。

控制項中的輸入事件處理常式

特定 Windows 執行階段控制項有時會在內部使用已處理的概念來輸入事件。 這可能會讓輸入事件似乎永遠不會發生,因為您的使用者程式碼無法處理它。 例如,Button 色彩包含有意處理一般輸入事件 PointerPressed 的邏輯。 這樣做是因為按鈕會引發 Click 事件,而 Click 事件是由按下指標的輸入所起始,以及由其他輸入模式所起始,例如處理按鍵,例如當按鈕聚焦時可以叫用按鈕的按鍵。 出於 Button 類別設計的目的,原始輸入事件會以概念方式處理,而使用者程式碼之類的類別取用者可以改為與控制項相關的 Click 事件互動。 Windows 執行階段 API 參考中特定控制項類別的主題通常會注意到類別實作的事件處理行為。 在某些情況下,您可以覆寫 OnEvent 方法來變更行為。 例如,您可以覆寫 Control.OnKeyDown 來變更 TextBox 衍生類別對按鍵輸入的反應。

註冊已處理路由事件的處理常式

我們稍早表示,將 [以處理的] 設定為 true 可防止呼叫大部分處理常式。 但是 AddHandler 方法提供一種技巧,讓您能夠附加一律針對路由叫用的處理常式,即使路由稍早的一些處理常式已將 [已處理的] 設定為 true,在共用事件資料中也是如此。 如果您使用的控制項在其內部撰寫或控制項特定邏輯中處理事件,則這項技術很有用。 但您仍想要從控制項執行個體或應用程式 UI 回應它。 但請謹慎使用這項技術,因為它可能會與 [已處理的] 目的相矛盾,而且可能會中斷控制項的預期互動。

只有具有對應路由事件識別碼的路由事件可以使用 AddHandler 事件處理技術,因為識別碼是 AddHandler 方法的必要輸入。 如需已提供路由事件識別碼的事件清單,請參閱 AddHandler 的參考文件。 在大多數情況下,這是我們稍早顯示之路由事件的相同清單。 例外狀況是清單中的最後兩個:GotFocusLostFocus 沒有路由事件識別碼,因此您無法針對這些識別碼使用 AddHandler

視覺化樹狀結構外部的路由事件

某些物件會參與與主要視覺化樹狀結構的關係,在概念上就像在主要視覺效果上重疊一樣。 這些物件不是將所有樹狀元素接到視覺化根之一般上層-下層關聯性的一部分。 這是任何顯示的快顯工具提示的情況。 如果您想要處理 Popup 或ToolTip 中的路由事件,請將處理常式放在 PopupToolTip 內的特定 UI 元素上,而不是 PopupToolTip 元素本身。 請勿依賴針對快顯工具提示內容執行的任何組合內部路由。 這是因為路由事件的事件路由僅適用於主要視覺化樹狀結構。 快顯工具提示不會被視為附屬 UI 元素的上層,而且永遠不會收到路由事件,即使它嘗試使用類似快顯預設背景的內容做為輸入事件的擷取區域也一樣。

點擊測試和輸入事件

判斷在 UI 中,元素是否可見滑鼠、觸控和手寫筆輸入的位置,稱為點擊測試。 針對觸控動作,以及針對觸控動作後果的互動特定或操作事件,元素必須可見點擊測試,才能成為事件來源,並引發與動作相關聯的事件。 否則,動作會將元素傳遞至視覺化樹狀結構中可能與該輸入互動的任何基礎元素或上層元素。 有幾個因素會影響點擊測試,但您可以藉由檢查其 IsHitTestVisible 屬性來判斷指定的元素是否可以引發輸入事件。 只有當元素符合下列準則時,這個屬性才會傳回 true

  • 元素的 Visibility 屬性值為 Visible
  • 元素的 BackgroundFill 屬性值不是 NullNullBrush 值會導致透明度和點擊測試不透明。 (若要讓元素變得透明,但也點擊可測試,請使用透明筆刷,而不是 null。)

注意:UIElement 不會定義 BackgroundFill,而是由不同的衍生類別定義,例如 ControlShape。 但是,不論哪一個子類別實作屬性,您用於前景和背景屬性的筆刷含意與點擊測試和輸入事件都相同。

  • 如果元素是控制項,其 IsEnabled 屬性值必須為 true
  • 元素在版面配置中必須有實際的維度。 ActualHeightActualWidth 為 0 的元素不會引發輸入事件。

某些控制項有特殊的點擊測試規則。 例如,TextBlock 沒有 Background 屬性,但在其維度的整個區域內仍可點擊測試。 影像MediaElement 控制項會在其定義的矩形維度上進行點擊測試,而不論顯示媒體來源檔案中的 Alpha 色板等透明內容。 Web 檢視控制項具有特殊的點擊測試行為,因為輸入可由裝載的 HTML 處理,並引發指令碼事件。

大部分的 Panel 類別和 Border 無法在自己的背景中測試,但仍可以處理從其包含之元素路由傳送的使用者輸入事件。

您可以判斷哪些元素與使用者輸入事件位於相同的位置,不論元素是否可點擊測試。 若要這樣做,請呼叫 FindElementsInHostCoordinates 方法。 正如名稱所暗示,這個方法會在相對於指定之主元素的位置尋找元素。 不過,套用的轉換和版面配置變更可以調整元素的相對座標系統,因此會影響在指定位置找到哪些元素。

命令

少數 UI 元素支援命令。 命令會在其基礎實作中使用輸入相關的路由事件,並藉由叫用單一命令處理常式,來處理相關的 UI 輸入 (特定指標動作,特定快速鍵)。 如果命令可用於 UI 元素,請考慮使用其命令 API 而不是任何特定的輸入事件。 您通常會將繫結參考用於定義資料檢視模型的類別屬性。 屬性會保存實作語言特定 ICommand 命令模式的具名命令。 如需詳細資訊,請參閱 ButtonBase.Command

Windows 執行階段中的自訂事件

為了定義自訂事件,您要如何新增事件,以及針對類別設計的意義,高度相依於您使用的程式設計語言。

  • 針對 C# 和 Visual Basic,您正在定義 CLR 事件。 您可以使用標準 .NET 事件模式,只要您不是使用自訂存取子 (add/remove)。 其他提示:
  • 對於 C++/CX,請參閱事件 (C++/CX)
    • 即使在您自己的自訂事件使用方式時,也請使用具名參考。 請勿將 Lambda 用於自訂事件,它可以建立循環參考。

您無法宣告 Windows 執行階段的自訂路由事件;路由事件僅限於來自 Windows 執行階段的集合。

定義自訂事件通常是在定義自訂控制項的練習中完成。 具有屬性變更回呼的相依性屬性,以及定義某些或所有案例中相依性屬性回呼所引發的自訂事件,是常見的模式。 控制項的使用者無法存取您定義的屬性變更回呼,但擁有可用的通知事件是下一個最好的事情。 如需詳細資訊,請參閱自訂相依性屬性