瞭解了路由事件後,這節來學習一下如何自定義路由事件。
【分析程式碼】
在演示程式碼前,我們不妨先看一段Button按鈕的Click路由事件原始碼,從原始碼中學習一下如何定義路由事件。
在ButtonBase中,跟Click路由事件相關的有如下四處程式碼:
程式碼一
程式碼二
程式碼三
程式碼四
第一段是宣告瞭ClickEvent這一路由事件物件,這個不用多說;
第二段是宣告瞭ClickEvent路由事件物件的包裝器,它類似於屬性的get,set,方便我們從外部把路由事件的處理器附加到路由事件上。當外部進行“+=”操作時,內部就會執行add塊,將事件處理附加到Click路由事件上,反之執行“-=”操作時,會執行remove塊中的內容;
第三段是構造方法中構建Click路由事件物件,跟建立依賴物件類似的是,路由事件物件的建立也不是直接new,而是通過EventManager類的RegisterRoutedEvent方法進行註冊,該方法第一個引數是路由事件的名稱,微軟約定路由事件名稱要跟路由事件物件的包裝器名稱一致,並且跟路由事件物件去掉Event字尾的字樣也要一致。第二個引數是指路由事件的策略,也就是事件傳播的形式,有如下三種列舉:
-
RoutingStrategy.Tunnel:隧道式,是指事件從最外層的控制元件開始路由,直到路由到控制元件自己,就像一條自上往下的隧道,從window控制元件一路通到當前觸發事件的控制元件;
-
RoutingStrategy.Bubble:冒泡式,這個跟隧道式相反,它是從觸發事件的控制元件向上傳播,直到最上層停止;
-
RoutingStrategy.Direct:直通式,跟原始事件模型一樣,不路由,直達事件處理器。
第三個引數是指定該路由事件的事件處理器是什麼型別,第四個引數是指定該路由事件物件的宿主型別,第四個引數跟第一個引數共同用於路由事件物件的內部建立使用:構建hash code,確定路由事件物件唯一性,同依賴屬性一致,在一個類中不能註冊兩個同名的路由事件物件。
第四段是激發Click路由事件的方法,事件引數就是在此方法中處理,它是路由事件傳播之源。
【自定義路由事件】
下面我們就來根據以上語法,基於ButtonBase建立自己的Click路由事件:
public class MyRoutedEventArgs : RoutedEventArgs { public MyRoutedEventArgs(RoutedEvent routedEvent, object source) : base(routedEvent, source) { } public string RoutedMessage { get; set; } } public class MyButton : ButtonBase { public static readonly RoutedEvent MessageEvent = EventManager.RegisterRoutedEvent("Message", RoutingStrategy.Bubble, typeof(EventHandler<MyRoutedEventArgs>), typeof(MyButton)); public event RoutedEventHandler Message { add { this.AddHandler(MessageEvent, value); } remove { this.RemoveHandler(MessageEvent, value); } } protected override void OnClick() { base.OnClick(); MyRoutedEventArgs eventArgs = new MyRoutedEventArgs(MessageEvent, this) { RoutedMessage = "自定義路由事件被觸發了" }; this.RaiseEvent(eventArgs); } }
上述程式碼中,我建立了一個MyButton,宣告瞭一個MessageEvent路由事件物件,值得注意的是,RegisterRoutedEvent的第三個引數我用的是:
typeof(EventHandler<MyRoutedEventArgs>)
而非:
typeof(RoutedEventHandler)
因為RoutedEventHandler的引數跟我自定義的事件引數不一致,需要使用EventHandler的泛型版指定我的事件引數型別,下面是RoutedEventHandler的宣告:
該引數型別是RoutedEventArgs,而我使用的是自定義的MyRoutedEventArgs型別。
XAML部分及事件處理器的程式碼為:
在外層Grid上設定MyButton的Message事件監聽及處理器。
執行效果如下:
點選“你好”,彈出MessageBox提示“自定義路由事件被觸發了”。