路由事件(
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這兩種傳播方式,所以一般...