筆記 簡譯 WPF的新特性 路由事件(1)

2021-04-15 12:10:27 字數 3491 閱讀 3011

路由事件(

routed event

就像

wpf在

.net

屬性之上新增了許多基礎結構一樣,它也在

.net

事件之上新增了許多基礎結構。路由事件是一種與樹上元素協同工作的事件,當它被觸發後,能夠沿著邏輯樹和視覺樹上

/下傳遞,觸發每個子元素的對應事件,不需要任何自定義的**。

事件路由幫助大多數應用程式遮蔽視覺樹的細節,是

wpf中「元素組合」得以成功的關鍵。例如,

button

公開了處理低階

mouseleftbuttondown

和keydown

的click

事件。當使用者在標準按鈕上單擊了滑鼠左鍵,實際上他們是與

buttonchrome

或textblock

視覺子元素進行互動的。由於事件沿著視覺樹向上傳遞,所以

button

最終收到這個事件並且能夠處理它。相似地,對於之前(在

xaml

揭秘中)

錄影機風格的

stop

按鈕,使用者可能直接是在

rectangle

邏輯子元素上單擊了滑鼠左鍵。由於事件沿著邏輯樹向上傳遞,

button

也將會收到這個事件並且可以處理它。

因此,我們可以在像

button

這樣的元素內嵌入任意複雜的內容,或者賦予它任意複雜的視覺樹。儘管如此,在任意內部元素上單擊滑鼠左鍵的行為都將導致

click

事件被父元素

button

觸發。試想如果沒有路由事件,那麼實現這樣的功能將不得不編寫不少**。

路由事件的行為和實現與依賴屬性很相似,讓我們先從路由事件的實現開始。

路由事件的實現

大多數情況下,路由事件與普通的

.net

事件看起來非常相似。與依賴屬性相同,沒有

.net

語言(除了

xaml

)知道路由事件的存在,對其的支援則完全基於

wpf api

。下例展示了

button

實現click

路由事件的方法,不過事實上

click

事件是由

button

的基類buttonbase

實現的,不過這並不影響我們的討論。

public

class

button : buttonbase

//事件包裝器(可選)

public

event

routedeventhandler click

remove

}protected

override

void onmouseleftbuttondown(mousebuttoneventargs e)

}路由事件的實現與依賴屬性的實現十分相似。它在實現型別中是乙個

routedevent

型別的物件,習慣上被

public static readonly

修飾,且擁有

event

字尾。eventmanager

的registerroutedevent

方法用來向事件系統進行註冊新的路由事件,並且僅在實現型別中可選的「事件包裝器」(如

click

事件)中呼叫

addhandler

和removehandler

方法來新增和移除它。這兩個方法不是從

dependencyobject

繼承而來的,而是來自

system.windows.uielement

(button

等的高層基類),負責在適當的路由事件身上附加或移除事件處理器(委託)。在

onmouseleftbuttondown

內部,uielement

定義的raiseevent

方法被呼叫,傳入引數分別為對應的路由事件物件和事件源的引用。

路由策略和事件處理器

註冊的時候,每個路由事件都會選擇一種路由策略。路由策略是事件觸發時沿元素樹傳遞的方式,

wpf的事件系統一共包含三種事件路由策略:(1

下降式

tunneling

):事件首先在根元素上被觸發,繼而沿著元素樹向下觸發子元素的相應事件,直到到達事件源子元素(或直到事件處理方法將這個事件標記為已處理)為止。(2

上公升式

bubbling

):事件首先在事件源元素上被觸發,繼而沿著元素樹向上觸發父元素的相應事件,直到達到根元素(或直到事件處理方法將這個事件標記為已處理)為止。(3

直接式

direct

):事件只能在事件源元素上被觸發。這與普通的

.net

事件類似,但它可以參與路由事件的特殊機制,如「事件觸發器」(

event trigger

)。路由事件的處理方法擁有和一般

.net

事件類似的簽名。第乙個引數是

system.object

型別的事件源物件

sender

,它儲存著附加了該處理函式的元素物件的引用;第二個引數是從

routedeventargs

(派生自

system.eventargs

)派生的類的例項e。

routedeventargs

公開了四個有用的屬性:(1

)source

:位於邏輯樹上的事件源元素(如

button)。(

2)originalsource

:位於視覺樹上的事件源元素(如

button

的buttonchrome

或textblock)。(

3)handled

:乙個布林變數,設定為

true

表示事件已被處理,它可以精確地中止上公升式和下降式路由事件的傳遞。(4

)routedevent

:真正的路由事件物件(如

button.clickevent 

),它對鑑別相同處理函式處理不同路由事件很有幫助。

source

和originalsource

的區別僅在於處理物理事件上,如滑鼠事件等。對於那些與視覺樹上元素不需要有直接關係的事件,

source

和originalsource

引用的是相同的物件,比如

click

事件(因為使用者可以通過鍵盤觸發它,如在擁有焦點的按鈕上按下空格鍵)。

WPF路由事件學習筆記

路由事件是具有更強傳播能力的事件 他們可在元素樹中向上冒泡和向下隧道傳播,並且沿著傳播路勁被事件處理程式處理。路由事件和依賴項屬性模型類似。wpf的 button 類提供了大家屬性的 click 事件,改時間繼承自抽象的 buttonbase基類 public abstract class butt...

WPF的路由事件

wpf中的事件為路由事件,所謂路由事件,msdn定義如下 功能定義 路由事件是一種可以針對元素樹中的多個偵聽器 而不是僅針對引發該事件的物件 呼叫處理程式的事件。實現定義 路由事件是乙個 clr 事件,可以由 routedevent 類的例項提供支援並由 windows presentation f...

WPF中路由事件的傳播

路由事件 routedevent 是wpf中新增的事件,使用起來與傳統的事件差別不大,但傳播方式是完全不同的。通過routingstrategy來定義傳播的方式 public enum routingstrategy wpf中的路由事件用的最多的就是tunnel和bubble這兩種傳播方式,所以一般...