1. 程式人生 > >WPF中的事件(二)- 自定義路由事件

WPF中的事件(二)- 自定義路由事件

自定義路由事件的新增,共分為三個步驟:

1、宣告並註冊路由事件
2、為路由事件新增CLR事件包裝
3、建立可以激發路由事件的方法

 以下例項,實現的功能是建立一個Button,每次點選該Button時激發自定義的路由事件ReportTime,傳遞按鈕被點選的時間。
     首先定義用於承載時間訊息的事件引數,主要充當在事件中傳遞的引數的載體,必須繼承自EventArgs類:
public class ReportTimeEventArgs : RoutedEventArgs
    {
        public ReportTimeEventArgs(RoutedEvent rountedEvent,object
source): base(rountedEvent,source) { } public DateTime ClickTime { get; set; } }
將按鈕點選的時間放到ReportTimeEventArgs類中,在激發路由事件時,事件傳遞的引數就是ReportTimeEventArgs類物件,而該物件儲存這按鈕被點選的時間。看其建構函式的兩個引數一個是路由事件的物件,另一個是該路由事件的宿主。
接下來,從Button繼承一個類,分別按照上述三個步驟新增自定義的路由事件:
class TimeButton:Button
    {
        //聲¦¨´明¡Â和¨ª注Á¡é冊¨¢路¡¤由®¨¦事º?件t
public static readonly RoutedEvent ReportTimeEvent = EventManager.RegisterRoutedEvent ("ReportTime", RoutingStrategy.Bubble, typeof(EventHandler< ReportTimeEventArgs >), typeof(TimeButton)); //CLR事º?件t包㨹裝Á¡ã器¡Â public event RoutedEventHandler ReportTime { add { this
.AddHandler(ReportTimeEvent,value);} remove { this.RemoveHandler(ReportTimeEvent, value); } } //激¡è發¤¡é路¡¤由®¨¦事º?件t,ê?用®?Click的Ì?方¤?法¤¡§ protected override void OnClick() { base.OnClick(); ReportTimeEventArgs args = new ReportTimeEventArgs(ReportTimeEvent, this); args.ClickTime = DateTime.Now; this.RaiseEvent(args); } }
來看宣告和註冊的路由事件,和依賴屬性類似,該路由事件也是static的和readoly的,也就是說是全域性範圍內的物件,其註冊函式包含四個引數,分別是:將會被封裝成的CLR事件包裝器名稱;路由事件的傳遞方式,是向下逐級傳遞,還是向上逐級傳遞,還是有目標的一次性傳遞;事件處理器的型別;宿主型別。
接下來看CLR事件的包裝器,不同於依賴屬性的SetValue和GetValue,這裡是利用add和Remove兩個函式來給路由事件分配事件處理器。

在Button類中的OnClick函式中,我們激發該路由事件。首先聲明瞭一個傳遞路由事件引數的ReportTimeEventArgs類物件,其後遭器由路由事件和Button的this構成,將其ClickTime屬性賦值為當前點選的時間,然後通過RaiseEvent這一虛擬函式激發該事件。RaiseEvent的引數是RoutedEventArgs型別物件,而在該物件中包含了這個全域性的路由事件和事件宿主資訊。當該在事件傳遞的路由節點中,如果配置了針對該事件的處理器,該節點就能從全域性找到該事件並進行相應操作。
搭建以下介面,每點選一次按鈕,就會在ListBox上顯示按鈕被點選的事件:

<Window x:Class="_8._10.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:_8._10"
        Title="MainWindow" Height="350" Width="525"
        local:TimeButton.ReportTime="ReportTimeHandler" x:Name="window">
    <Grid local:TimeButton.ReportTime="ReportTimeHandler" Name="grid">
        <StackPanel local:TimeButton.ReportTime="ReportTimeHandler" Name="stackpanel">
            <ListBox Width="400" Height="220" Name="list" />
            <local:TimeButton x:Name="timebutton" Width="40" Height="80" Content="報À¡§時º¡À" local:TimeButton.ReportTime="ReportTimeHandler"/>
        </StackPanel>
    </Grid>
</Window>

點選按鈕,效果如下:
這裡寫圖片描述