日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

WPF,Silverlight与XAML读书笔记第八 - WPF新概念之三路由事件

發(fā)布時(shí)間:2024/4/17 asp.net 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 WPF,Silverlight与XAML读书笔记第八 - WPF新概念之三路由事件 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

說明:本系列基本上是《WPF揭秘》的讀書筆記。在結(jié)構(gòu)安排與文章內(nèi)容上參照《WPF揭秘》的編排,對(duì)內(nèi)容進(jìn)行了總結(jié)并加入一些個(gè)人理解。

?

????? 路由事件是專門設(shè)計(jì)用于在元素樹中使用的事件。當(dāng)路由事件觸發(fā)后,其可以向上或向下遍歷可視樹和邏輯樹,并且持續(xù)在每個(gè)元素上觸發(fā)。

????? 我們以按鈕為例,說明路由事件的作用。在WPF之前的Windows客戶端技術(shù)WinForm中按鈕僅僅就是一個(gè)System.Windows.Forms命名空間下的Button類的對(duì)象。對(duì)其的點(diǎn)擊等操作可以直接捕獲,但是WPF中展現(xiàn)給你的按鈕的組成可能會(huì)很復(fù)雜。其可能包括ButtonChrome或者TextBlock等可視子元素或者包含Rectangle等邏輯子元素,這時(shí)候?qū)σ粋€(gè)按鈕的點(diǎn)擊(MouseLeftButtonDown事件或KeyDown事件)可能實(shí)際發(fā)生在其可視子元素或邏輯子元素上,這時(shí)使用路由事件,由于其遍歷可視樹/邏輯樹,ButtonClick(路由)事件最終會(huì)被觸發(fā)。

?

路由事件的實(shí)現(xiàn)

????? 同依賴屬性,路由事件也只有XAML語言天生支持,在傳統(tǒng)過程式代碼中注冊(cè)路由事件的代碼如下(以ButtonClick路由事件為例)。首先注意的是,路由事件的約定名稱是在傳統(tǒng)事件名稱的后面加上Event后綴(類似依賴屬性的Property后綴)。

示例代碼:

//聲明路由事件 public?static?readonly?RoutedEvent?ClickEvent;

首先在Button類中聲明這個(gè)路由事件。接著,

//注冊(cè)路由事件 Button.ClickEvent?=?EventManager.RegisterRoutedEvent( "Click", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(Button) );

Button類的靜態(tài)構(gòu)造函數(shù)中初始化這個(gè)路由事件。

最后添加可選的.NET事件包裝器

//(可選).NET事件包裝器 public?event?RoutedEventHandler?Click {add?{???AddHandler(Button.ClickEvent,?value);?}remove?{???RemoveHandler(Button.ClickEvent,?value);?} }

觸發(fā)路由事件的代碼(可以位于OnMouseLeftButtonDown處理程序中)

RaiseEvent(new?RoutedEventArgs(Button.ClickEvent,?this));

分析:

RegisterRoutedEvent方法中傳入的第一個(gè)參數(shù)定義了一個(gè)普通的.NET事件,事件包裝器對(duì)這個(gè)事件進(jìn)行包裝。這樣可以使過程式代碼中事件使用更接近原有模式,并且XAML中也可以更方便的添加事件處理程序。

?

.NET事件包裝器與內(nèi)部實(shí)現(xiàn)

事件包裝器內(nèi)部調(diào)用的AddHandlerRemoveHandler方法位于繼承自DependencyObject對(duì)象的UIElement對(duì)象。這兩個(gè)方法分別可以向一個(gè)適當(dāng)?shù)穆酚墒录砑右粋€(gè)委托對(duì)象及由路由事件移除一個(gè)委托對(duì)象。事件包裝器中只能調(diào)用AddHandlerRemoveHandler,不能做它用,這點(diǎn)與屬性包裝器類似。

?

路由策略

在前文注冊(cè)路由事件的代碼中你已經(jīng)見過RoutingStrategy這個(gè)枚舉。與此相關(guān)的就是路由策略的概念,路由策略指的是事件觸發(fā)遍歷元素樹的方式。有以下三種:

  • Tunneling(管道傳遞)

    事件首先在根元素上被觸發(fā),然后向下沿著樹中每一個(gè)元素傳遞,直到到達(dá)源元素為止(或者直到處理程序把事件標(biāo)記為已處理為止)。

  • ? Bubbling(冒泡傳遞)

    事件首先在源元素上被觸發(fā),然后向上沿著樹中每一個(gè)元素傳遞,直到到達(dá)根元素為止(或者直到處理程序把事件標(biāo)記為已處理為止)。

  • Direct(直接)

    事件僅在源元素上觸發(fā)。這與普通.NET事件的行為基本相同。不同之處在于此類事件仍會(huì)參與事件觸發(fā)器等路由事件的特定機(jī)制。

?

路由事件處理程序

???????? 路由事件處理程序(RoutedEventHandler)與普通的.NET事件的處理程序的設(shè)計(jì)遵循相同的模式:第一個(gè)參數(shù)為名為SenderSystem.Object對(duì)象表示流處理程序被添加到的元素。第二個(gè)元素是名為e(通常習(xí)慣)的派生自RoutedEventArgs或其子類(這些類都派生自System.EventArgs類)的對(duì)象。這個(gè)對(duì)象有4個(gè)屬性,通過它們變向擴(kuò)展了提供給路由事件的參數(shù)。

  • Source:邏輯樹中第一個(gè)觸發(fā)該事件的元素。

  • OriginalSource:可視樹中第一個(gè)觸發(fā)該事件的元素(如點(diǎn)擊Button首先觸發(fā)的可視樹為ButtonChrome,這個(gè)及前者的屬性多用于區(qū)分鼠標(biāo)事件之類的物理事件)。

  • Handled:布爾值,設(shè)置為true來標(biāo)記事件為已處理,用于停止TunnelingBubbling事件在樹上的觸發(fā)。

  • RoutedEvent:真正的路由事件對(duì)象(如Button.ClickEvent),當(dāng)多個(gè)路由事件共享一個(gè)事件處理函數(shù)時(shí),此屬性可以用來區(qū)分這個(gè)事件。

?

路由事件的作用

?????? 路由事件定義于UIElement類中,主要用于鍵盤,鼠標(biāo),觸控筆之類觸發(fā)的物理事件。而且這些路由事件往往是成對(duì)定義的即對(duì)于一個(gè)物理事件存在一個(gè)管道事件與一個(gè)冒泡事件相對(duì)應(yīng)。其中管道事件的慣例是以Preview前綴開頭。這個(gè)管道事件會(huì)在對(duì)應(yīng)的冒泡事件之前觸發(fā),WPF的內(nèi)部元素也只會(huì)響應(yīng)冒泡事件。所以你可以在管道事件發(fā)生的過程中預(yù)覽事件或者采取停止事件等措施。(實(shí)例:對(duì)于TextBox可以處理其KeyDown的管道事件(PreviewKeyDown事件)來嚴(yán)格限制其中輸入的內(nèi)容)。如果內(nèi)容不合要求則在PreviewKeyDown事件發(fā)生的過程中標(biāo)記事件為已處理,這樣KeyDown冒泡事件將不再觸發(fā),則對(duì)TextBox的操作不會(huì)有任何效果。

?????? 注意在冒泡事件由source逐級(jí)向聲明其的對(duì)象觸發(fā)的過程中,可以被其中的接受事件的對(duì)象處理,并終止此冒泡事件。

?

最佳控制事件的方式

????? 在路由事件的Preview版本中添加事件處理程序。

路由事件(管道或冒泡)的終止都是表面的,其只是被標(biāo)記為已處理,但事件傳遞會(huì)繼續(xù),只是事件處理程序只處理沒有標(biāo)記為已處理的事件。

路由事件既可以沿可視樹傳遞,也可以沿邏輯樹傳遞。

?

附加事件

????? 當(dāng)樹中(邏輯樹或可視樹)的每個(gè)元素都有路由事件時(shí),路由事件(管道類型與冒泡類型)自然可以在其中傳遞。有了附加事件,事件傳遞也可以在一個(gè)沒有定義這些事件的元素上進(jìn)行。由于定義附加事件的元素本身不支持此事件,所以要在此附加事件上定義處理此事件(路由事件)的方法的名稱。

示例:如下XAML代碼將ListBoxSelectionChanged路由事件與ButtonClick路由事件作為附加事件提供給window元素。

<Window ...ListBox.SelectionChanged="ListBox_SelectionChanged" Button.Click="Button_Click">

與這些XAML對(duì)應(yīng)的過程代碼實(shí)現(xiàn):

this.AddHandler(ListBox.SelectionChangedEvent,?new?SelectionChangedEventHandler(ListBox_SelectionChanged)); this.AddHandler(Button.ClickEvent,?new?RoutedEventHandler(Button_Click));

需要注意的是這些過程代碼應(yīng)置于InitializeComponent()后。

?

本文完

?

參考:

WPF揭秘》

轉(zhuǎn)載于:https://www.cnblogs.com/lsxqw2004/archive/2011/09/08/4554476.html

總結(jié)

以上是生活随笔為你收集整理的WPF,Silverlight与XAML读书笔记第八 - WPF新概念之三路由事件的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。