</nav>
讯享网
Windows Presentation Foundation (WPF) 應用程式開發人員和元件作者可以使用路由事件,透過元素樹狀結構傳播事件,並在樹狀結構中的多個接聽程式上叫用事件處理常式。 通用語言執行平台 (CLR) 事件中不提供這些功能。 數個 WPF 事件是路由事件,例如 (部分機器翻譯)。 本文討論基本的路由事件概念,並提供何時及如何回應路由事件的指引。
本文假設您對通用語言執行平台 (CLR)、物件導向程式設計,以及如何將 WPF 元素版面配置概念化為樹狀結構有基本了解。 若要遵循本文中的範例,建議您先熟悉 Extensible Application Markup Language (XAML),並了解如何撰寫 WPF 應用程式 (部分機器翻譯)。
您可以從功能或實作觀點來考量路由事件:
- 從功能觀點來看,路由事件是一種事件類型,可在元素樹狀結構中的多個接聽程式上叫用處理常式,而不只是在事件來源上。 事件接聽程式是附加和叫用事件處理常式所在的元素。 事件來源是原本引發事件的元素或物件。
- 從實作觀點來看,路由事件是向 WPF 事件系統註冊的事件,由 (英文) 類別的執行個體所支援,並由 WPF 事件系統處理。 一般而言,路由事件是使用 CLR 事件「包裝函式」來實作,以啟用在 XAML 和程式碼後置中附加處理常式,就像 CLR 事件一樣。
WPF 應用程式通常包含許多元素,這些元素是在 XAML 中宣告或在程式碼中具現化。 應用程式的元素存在於其元素樹狀結構中。 根據路由事件的定義方式,在來源元素上引發事件時,其會:
- 在元素樹狀結構中從來源元素到根元素 (通常是頁面或視窗) 進行事件反昇。
- 在元素目樹狀結構中從根元素到來源元素往下進行通道處理。
- 不周遊元素樹狀結構,而只會發生在來源元素上。
考慮下列部分元素樹狀結構:
讯享网
元素樹狀結構會轉譯,如下所示:
這三個按鈕中的每一個都是潛在的 (部分機器翻譯) 事件來源。 按兩下其中一個按鈕時,其會引發從按鈕到根元素事件反昇的 事件。 (部分機器翻譯) 和 (部分機器翻譯) 元素未附加事件處理常式,但 (部分機器翻譯) 有。 樹狀結構中可能較高且未顯示的其他元素也附加了 事件處理常式。 當 事件到達 元素時,WPF 事件系統會叫用附加至它的 處理常式。 範例中 事件的事件路由為: -> -> -> 連續父元素。
以下是一些促使路由事件概念,並將它與典型 CLR 事件區分的案例:
- 控制項組合和封裝:WPF 中的各種控制項都有豐富的內容模型。 例如,您可以將影像放在 (部分機器翻譯) 內,這可有效地延伸按鈕的視覺化樹狀結構。 但是,新增的影像不得中斷按鈕的點擊測試行為,其必須在使用者按下影像像素時做出回應。
- 單一處理常式附件點:您可以為每個按鈕的 事件註冊處理常式,但使用路由事件時,您可以附加單一處理常式,如上一個 XAML 範例所示。 這可讓您變更單一處理常式底下的元素樹狀結構,例如新增或移除更多按鈕,而不需要註冊每個按鈕的 事件。 引發 事件時,處理常式邏輯可以判斷事件的來源。 在先前顯示的 XAML 元素樹狀結構中指定的下列處理常式包含該邏輯:
讯享网
- 類別處理:路由事件支援您在類別中定義的類別事件處理常式。 類別處理常式會在類別的任何執行個體上處理相同事件的任何執行個體處理常式之前處理事件。
- 在沒有反映的情況下參考事件:每個路由事件都會建立 (英文) 欄位識別碼,以提供不需要靜態或執行階段反映來識別事件的強固事件識別技術。
路由事件是向 WPF 事件系統註冊的事件,由 (英文) 類別的執行個體所支援,並由 WPF 事件系統處理。 從註冊 (英文) 取得的 執行個體通常會儲存為註冊它之類別的 成員。 該類別稱為事件「擁有者」類別。 路由事件通常會實作同名 CLR 事件「包裝函式」。 CLR 事件包裝函式包含 和 存取子,可透過語言專有事件語法在 XAML 和程式碼後置中啟用附加處理常式。 和 存取子會覆寫其 CLR 實作,並呼叫路由事件 (部分機器翻譯) 和 (英文) 方法。 路由事件支援和連線機制在概念上類似於相依性屬性是 CLR 屬性的方式,該屬性是由 類別所支援,並向 WPF 屬性系統註冊。
下列範例會註冊 路由事件、儲存傳回的 執行個體,並實作 CLR 事件包裝函式。
讯享网
路由事件會使用下列其中一個路由傳送策略:
- 事件反昇 (英文):一開始,會叫用事件來源上的事件處理常式。 路由事件接著會路由傳送至後續父元素,進而接著叫用其事件處理常式,直到到達元素樹狀結構根目錄為止。 大部分的路由事件會使用事件反昇路由傳送策略。 事件反昇的路由事件通常是用來報告來自複合控制項或其他 UI 元素的輸入或狀態變更。
- 通道︰一開始會叫用元素樹狀結構根元素上的事件處理常式。 路由事件接著會路由傳送至後續子元素,進而接著叫用其事件處理常式,直到到達事件來源為止。 遵循通道路由的事件也稱為預覽事件。 WPF 輸入事件通常會實作為預覽和事件反昇配對。
- 直接 (英文):只會叫用事件來源上的事件處理常式。 此非路由策略類似於 Windows Forms UI 架構事件,也就是標準 CLR 事件。 不同於 CLR 事件,直接路由事件支援類別處理 (部分機器翻譯),而且可由 EventSetters (部分機器翻譯) 和 EventTriggers (部分機器翻譯) 使用。
身為應用程式開發人員,您不一定需要知道或在意您正在處理的事件是否已實作為路由事件。 路由事件有特殊的行為,但是,如果您正在引發事件的元素上處理事件,則大多不會看見該行為。 不過,當您想要將事件處理常式附加至父元素,以處理子元素所引發的事件時 (例如在複合控制項內),路由事件是相關的。
路由事件接聽程式不需要其處理的路由事件為其類別的成員。 任何 或 可以是任何路由事件的事件接聽程式。 由於視覺元素衍生自 或 ,因此您可以使用路由事件作為概念性的「介面」,以支援在應用程式中的不同元素之間交換事件資訊。 路由事件的「介面」概念特別適用於輸入事件 (部分機器翻譯)。
路由事件支援在事件路由上的元素之間交換事件資訊,因為每個接聽程式都能夠存取相同的事件資料執行個體。 如果某個元素在事件資料中變更某個項目,事件路由中的後續元素就會看到該變更。
除了路由層面之外,您可以選擇實作路由事件,而不是標準 CLR 事件,原因如下:
- 某些 WPF 樣式和範本化功能 (例如 EventSetters (部分機器翻譯) 和 EventTriggers (部分機器翻譯)) 要求參考的事件必須是路由事件。
- 路由事件支援類別事件處理常式,其會在接聽程式類別的任何實執行個體上處理相同事件的任何實例處理程式之前處理事件。 此功能在控制項設計中非常有用,因為您的類別處理常式可以強制執行事件驅動的類別行為,這些行為無法由執行個體處理常式意外隱藏。
在 XAML 中,您可以透過將事件名稱宣告為事件接聽程式元素上的屬性,以將事件處理常式附加至元素。 屬性值是您的處理常式方法名稱。 處理常式方法必須在 XAML 頁面的程式碼後置部分類別中實作。 事件接聽程式是附加和叫用事件處理常式所在的元素。
針對屬於接聽程式類別成員 (繼承或其他) 的事件,您可以附加處理常式,如下所示:
如果事件不是接聽程式類別的成員,您必須以 的形式使用限定的事件名稱。 例如,由於 類別不會實作 事件,因此若要將處理常式附加至反昇至該元素之 事件的 ,您必須使用限定的事件名稱語法:
讯享网
程式碼後置中事件處理常式方法的簽章必須符合路由事件的委派類型。 事件之 委派的 參數會指定要附加事件處理常式的元素。 委派的 參數包含事件資料。 事件處理常式的相容程式碼後置實作可能是:
讯享网
雖然 是基本的路由事件處理常式委派,但某些控制項或實作案例需要支援更特殊化事件資料的不同委派。 例如,針對 (部分機器翻譯) 路由事件,您的處理常式應該實作 (部分機器翻譯) 委派。 如此一來,處理常式程式碼就可以存取事件資料 (其中包含拖曳作業中的剪貼簿承載) 中的 屬性。
用於新增路由事件處理常式的 XAML 語法與標準 CLR 事件處理常式相同。 如需在 XAML 中新增事件處理程式的詳細資訊,請參閱在 WPF 中 XAML。 如需如何使用 XAML 將事件處理常式附加至元素的完整範例,請參閱如何處理路由事件。
若要使用程式碼將路由事件的事件處理常式附加至元素,您通常有兩個選項:
- 直接呼叫 (部分機器翻譯) 方法。 路由事件處理常式一律能以此方式附加。 此範例會使用 方法,將 事件處理常式附加至按鈕:
讯享网
若要將按鈕的 事件的處理常式附加至事件路由中的不同元素,例如名為 的 :
讯享网
- 如果路由事件實作 CLR 事件包裝函式,請使用語言專有的事件語法來新增事件處理常式,就像針對標準 CLR 事件一樣。 大部分現有的 WPF 路由事件都會實作 CLR 包裝函式,從而啟用語言專有的事件語法。 此範例會使用語言專有語法,將 事件處理常式附加至按鈕:
讯享网
如需如何在程式碼中附加事件處理常式的範例,請參閱如何使用程式碼新增事件處理常式。 如果您使用 Visual Basic 撰寫程式碼,您也可以使用 關鍵字,將處理常式新增為處理常式宣告的一部分。 如需詳細資訊,請參閱 Visual Basic 和 WPF 事件處理。
所有路由事件都會共用事件資料的基底類別,也就是 (部分機器翻譯) 類別。 類別會定義布林值 (部分機器翻譯) 屬性。 屬性的目的是讓事件路由上的任何事件處理常式將路由事件標示為「已處理」。 若要將事件標示為已處理,請在事件處理常式程式碼中將 的值設定為 。
的值會影響路由事件在沿著事件路由移動時的處理方式。 在路由事件的共用事件資料中,若 為 ,則附加至沿著事件路由之其他元素的處理常式通常不會針對該特定事件執行個體叫用。 針對最常見的處理常式案例,將事件標示為已處理會有效地讓沿著事件路由的後續處理常式 (無論是執行個體或類別處理常式) 停止回應該特定事件執行個體。 不過,在需要事件處理常式回應已標示為已處理之路由事件的罕見情況下,您可以:
- 使用 (部分機器翻譯) 多載在程式碼後置中附加處理常式,並將 參數設定為 。
- 將 (英文) 屬性設定為 或 。
的概念可能會影響您設計應用程式和撰寫事件處理常式程式碼的方式。 您可以將 概念化為處理路由事件的簡單通訊協定。 使用此通訊協定的方式由您決定,但預期的 參數用法如下:
- 如果將路由事件標示為已處理,則不需再次透過沿著該路由的其他元素來處理它。
- 如果未將路由事件標示為已處理,則事件路由中稍早的接聽程式沒有事件的處理常式,或沒有任何已註冊的處理常式回應事件,以讓事件標示為已處理。 目前接聽程式上的處理常式有三個可能的行動步驟:
- 不採取任何動作。 事件會保持未處理狀態,而且會路由傳送至樹狀結構中的下一個接聽程式。
- 執行程式碼以回應事件,但不會將事件標示為已處理。 事件會保持未處理狀態,而且會路由傳送至樹狀結構中的下一個接聽程式。
- 執行程式碼以回應事件,將事件標示為已處理。 在事件資料中將事件標示為已處理。 事件仍會路由傳送至樹狀結構中的下一個接聽程式,但大部分接聽程式不會叫用進一步的處理常式。 例外狀況是具有已特別向設定為 的 註冊之處理常式的接聽程式。
如需有關處理路由事件的詳細資訊,請參閱將路由事件標記為已處理以及類別處理。
雖然只處理引發之物件上事件反昇之路由事件的開發人員可能不關心其他接聽程式,但最好還是將事件標示為已處理。 如果進一步沿著事件路由上的元素有相同路由事件的處理常式,則這樣做可防止非預期的副作用。
路由事件處理常式可以是實例處理常式或類別處理常式。 指定類別的類別處理常式,會在任何實例處理常式對該類別任何實例上的相同事件做出回應之前叫用。 由於此行為,當路由事件標示為已處理時,其通常也會在類別處理常式中標示為已處理。 類別處理常式有兩種類型:
- 靜態類別事件處理常式,其註冊方式為在靜態類別建構函式內呼叫 方法。
- 覆寫類別事件處理常式,其註冊方式為覆寫基底類別虛擬事件方法。 基底類別虛擬事件方法主要存在於輸入事件中,且名稱開頭為 On<event name> 以及 OnPreview<event name>。
某些 WPF 控制項具有特定路由事件的固有類別處理。 類別處理可能會提供路由事件從未引發的外表,但實際上,它被標示為由類別處理常式處理。 如果需要事件處理常式回應已處理的事件,您可以向設定為 的 註冊處理常式。 如需有關實作自己的類別處理常式或因應不想要的類別處理的詳細資訊,請參閱將路由事件標記為已處理以及類別處理。
XAML 語言也定義為特殊事件,稱為 附加事件 。 附加事件可用來在非元素類別中定義新的路由事件,並在樹狀結構中的任何元素上引發該事件。 若要這樣做,您必須將附加事件註冊為路由事件,並提供支援附加事件功能的特定支援程式碼。 由於附加事件註冊為路由事件,因此在元素上引發時,會透過元素樹狀結構散佈。
在 XAML 語法中,附加事件是由其事件名稱和擁有者類型所指定,格式為 。 因為事件名稱限定為其擁有者類型的名稱,因此語法可讓事件附加至可具現化的任何元素。 對於附加至事件路由中任意元素的一般路由事件,此語法也適用於其處理常式。 您也可以在處理常式應該附加至的物件上呼叫 方法,在程式碼後置中針對附加事件附加處理常式。
WPF 輸入系統會廣泛使用附加事件。 不過,幾乎所有附加事件都會透過基礎元素呈現為相等的非附加路由事件。 您很少會直接使用或處理附加事件。 例如,透過相等的 路由事件在 上處理基礎附加 事件,比在 XAML 或程式碼後置中使用附加事件語法更為容易。
如需 WPF 中附加事件的詳細資訊,請參閱附加事件概觀。
語法會使用其擁有者類型的名稱來限定事件名稱。 此語法可讓事件附加至任何元素,而不只是將事件實作為其類別成員的元素。 針對沿著事件路由任意元素上的附加事件或路由事件在 XAML 中附加處理常式時,適用該語法。 請考慮您想要將處理常式附加至父元素,以處理子元素上引發的路由事件的案例。 如果父元素沒有路由事件做為成員,您必須使用限定的事件名稱語法。 例如:
在範例中,在其中新增事件處理常式的父元素接聽程式是 (部分機器翻譯)。 不過, (部分機器翻譯) 路由事件會在 (部分機器翻譯) 類別上實作和引發,並透過繼承提供給 (部分機器翻譯) 類別。 雖然 (部分機器翻譯) 類別「擁有」 事件,但路由事件系統允許任何路由事件的處理常式附加至任何 (部分機器翻譯) 或 (部分機器翻譯) 執行個體接聽程式,否則這些接聽程式會有 CLR 事件的接聽程式。 這些限定事件屬性名稱的預設 命名空間通常是預設的 WPF 命名空間,但您也可以為自訂路由事件指定前置命名空間。 如需 的詳細資訊,請參閱 WPF XAML 的 XAML 命名空間和命名空間對應。
WPF 平台內路由事件的一個常見應用是輸入事件 (部分機器翻譯)。 依照慣例,遵循通道路由的 WPF 路由事件具有前面加上「Preview」的名稱。 「Preview」字首表示預覽事件會在配對的事件反昇事件開始之前完成。 輸入事件通常會成對出現,其中一個是預覽事件,而另一個則是事件反昇路由事件。 例如, 與 。 事件配對會共用相同的事件資料執行個體,這是針對 和 為 (部分機器翻譯) 類型。 有時,輸入事件只會有事件反昇版本,或只有直接路由版本。 在 API 文件中,路由事件主題會交叉參考路由事件配對,並釐清每個路由事件的路由策略。
會實作成對的 WPF 輸入事件,以便輸入裝置中的單一使用者動作 (例如按下滑鼠按鍵) 將會依序引發預覽和事件反昇路由事件。 首先,會引發預覽事件並完成其路由。 在預覽事件完成時,會引發事件反昇事件並完成其路由。 實作類別中引發事件反昇事件的 (英文) 方法呼叫會針對事件反昇事件重複使用來自預覽事件的事件資料。
標示為已處理的預覽輸入事件不會針對預覽路由的其餘部分叫用任何以正常方式註冊的事件處理常式,而且不會引發配對的事件反昇事件。 此處理行為適用於下列複合控制項設計人員:想要在其控制項的最上層報告點擊測試型輸入事件或以焦點為基礎的輸入事件。 控制項的最上層元素有機會從控制項子元件對預覽事件進行類別處理,以便以最上層控制項專有事件來「取代」它們。
如需輸入事件處理如何運作的圖表說明,請考慮下列輸入事件範例。 在下列樹狀結構圖中, 是 和 配對事件的來源:
在分葉元素 #2 上執行滑鼠按下動作之後的事件處理順序為:
- 根元素上的 通道事件。
- 中繼元素 #1 上的 通道事件。
- 分葉元素 #2 上的 通道事件,也就是來源元素。
- 分葉元素 #2 上的 事件反昇事件,也就是來源元素。
- 中繼元素 #1 上的 事件反昇事件。
- 根元素上的 事件反昇事件。
路由事件處理常式委派提供對兩個物件的參考︰引發事件的物件,以及已叫用處理常式的物件。 事件第一次引發的物件是由事件資料中的 (英文) 屬性所報告。 已叫用處理常式的物件是由 sender (部分機器翻譯) 參數所報告。 針對任何指定的路由事件執行個體,引發事件的物件不會隨著事件在元素樹狀結構中移動而變更,但 會。 在上圖的步驟 3 和 4 中, 和 是相同的物件。
如果您的輸入事件處理常式完成處理事件所需的應用程式專有邏輯,您應該將輸入事件標示為已處理。 一般而言,一旦將輸入事件標示為 (部分機器翻譯),就不會叫用沿著事件路由的進一步處理常式。 不過,即使事件標示為已處理,也會叫用已向設定為 之 參數註冊的輸入事件處理常式。 如需詳細資訊,請參閱預覽事件和將路由事件標記為已處理以及類別處理。
預覽和事件反昇事件配對的概念,其中共用事件資料和循序引發預覽事件,然後引發事件反昇事件,僅適用於某些 WPF 輸入事件,不適用於所有路由事件。 如果您實作自己的輸入事件來解決進階案例,請考慮遵循 WPF 輸入事件配對方法。
如果您要實作自己的複合控制項來回應輸入事件,請考慮使用預覽事件來隱藏子元件上引發的輸入事件,並取代為代表完整控制項的最上層事件。 如需詳細資訊,請參閱將路由事件標記為已處理以及類別處理。
如需 WPF 輸入系統以及一般應用程式案例中輸入如何與事件互動的詳細資訊,請參閱輸入概觀 (部分機器翻譯)。
在標記樣式中,您可以使用 (部分機器翻譯) 來包含一些預先宣告的 XAML 事件處理語法。 處理 XAML 時,會將參考的處理常式新增至樣式執行個體。 您只能針對路由事件宣告 。 在下列範例中,參考的 事件處理常式方法會在程式碼後置中實作。
讯享网
節點可能已經包含與指定類型控制項相關的其他樣式資訊,而且讓 (部分機器翻譯) 成為那些樣式的一部分可促進程式碼重複使用 (即使是在標記層級)。 此外, 會將處理常式的方法名稱從一般應用程式和頁面標記抽象化。
另一個結合 WPF 路由事件和動畫功能的特殊語法是 。 使用 時,您只能針對路由事件宣告 。 一般而言, 會宣告為樣式的一部分,但 可在頁面層級元素上宣告為 (部分機器翻譯) 集合的一部分,或在 (部分機器翻譯) 中宣告。 可讓您指定每當路由事件到達其路由中宣告該事件的 時,就會執行 。 不只是處理事件,並導致它啟動現有的分鏡腳本的優點是, 提供對分鏡腳本及其運行時間行為的更佳控制。 如需詳細資訊,請參閱在分鏡腳本開始後使用事件觸發程序進行控制 (部分機器翻譯)。
當在您自己的類別中建立自訂路由事件時,可以使用本文中的概念和指引作為起點。 您也可以使用特殊化事件資料類別和委派來支援自訂事件。 路由事件擁有者可以是任何類別,但路由事件必須由 (部分機器翻譯) 或 (部分機器翻譯) 衍生類別引發及處理,才能有用。 如需自訂事件的詳細資訊,請參閱建立自訂路由事件。
- 將路由事件標記為已處理以及類別處理
- 輸入概觀
- 命令概觀
- 自訂相依性屬性
- WPF 中的樹狀結構
- 弱式事件模式

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/159782.html