WPF繼續響應被標記為已處理事件的方法

2022-01-13 14:01:24 字數 4153 閱讀 2107

wpf中在冒泡事件或者隧道事件會隨其層間關係在visual tree上層層傳遞,但是,某些事件傳遞到某些控制項是即會」終止「(不再響應相應的註冊事件),給人一種事件終結者的印象。例如:textbox對mousdown事件。

產生原因:事件處理到達該控制項後,其事件物件屬性handled被標記為true。wpf事件引擎在處理控制項對應事件時,若檢測到該屬性為true,就不會呼叫相應的處理程式。即 wpf路由事件被標記為handled以後, 並不是不在visual tree上傳遞了;而是,事件引擎不再去呼叫這個事件的handler了。

若仍想再其上層元素中(上層是相對事件的傳遞方向而言)仍然處理響應的事件,解決方式:

1、若上層控制項可以註冊相應事件。即沒有重寫對應控制項的template屬性。直接上**:

<

grid

mousedown

="grid_mousedown"

>

<

textbox

name

="txt1"

text=""

mousedown

="txt_mousedown"

/>

grid

>

1

private

void txt_mousedown(object

sender, mouseeventargs e)26

7private

void grid_mousedown(object

sender, mouseeventargs e)

8

2、當自定義控制項模板時,繫結模版事件不起效,此時用上面的方法不再生效。例如:自定義列表控制項模版樣式

<

usercontrol

x:class

="test"

xmlns

=""xmlns:x

=""xmlns:mc

=""xmlns:d

=""mc:ignorable

="d"

d:designheight

="290"

d:designwidth

="180"

>

<

grid

name="gridmain"

>

<

itemscontrol

focusable

="false"

background

="transparent"

itemssource=""

>

<

itemscontrol.template

>

<

controltemplate

targettype

="itemscontrol"

>

<

border

x:name

="scrborder"

>

<

scrollviewer

x:name

="scrollviewer"

verticalscrollbarvisibility

="auto"

horizontalscrollbarvisibility

="auto"

padding=""

mouseleftbuttondown

="mouseleftbuttondown"

>

<

itemspresenter

/>

scrollviewer

>

border

>

controltemplate

>

itemscontrol.template

>

<

itemscontrol.itemtemplate

>

<

datatemplate

>

<

grid

>

<

grid.columndefinitions

>

<

columndefinition

width

="*"

/>

<

columndefinition

width

="auto"

/>

<

columndefinition

width

="auto"

/>

grid.columndefinitions

>

<

textblock

text=""

grid.column

="0"

/>

<

textblock

text=""

margin

="0"

grid.column

="1"

/>

<

textblock

text=""

grid.column

="2"

margin

="3,0,15,0"

/>

grid

>

datatemplate

>

itemscontrol.itemtemplate

>

<

itemscontrol.itemspanel

>

<

itemspaneltemplate

>

<

stackpanel

>

stackpanel

>

itemspaneltemplate

>

itemscontrol.itemspanel

>

<

itemscontrol.itemcontainerstyle

>

<

style

>

<

setter

property

="control.margin"

value

="1"

/>

style

>

itemscontrol.itemcontainerstyle

>

itemscontrol

>

grid

>

usercontrol

>

scrollviewer在控制項模版中,scrollviewer的mousebuttondown事件處理事件如下:斷點設定會發現滑鼠點選時並不會觸發。

1

private

void mouseleftbuttondown(object

sender, mousebuttoneventargs e)

2

解決辦法:uielement.addhandler 方法:

大體意思:由於wpf事件visual tree上傳遞過程中,某個元素將該事件標記為已處理,導致事件在傳遞時不再繼續有響應,(原因:handled被標記為true)如果希望後續元素也能響應此方法,可以使用此方法。

因此我們可以在上面usercontrol的建構函式中新增下面**:表示gridmain處理相應滑鼠點選事件

1

public

usercontrol()

2

再次斷點除錯mouseleftbuttondown,會發現斷點命中。

addhandler這個**的關鍵點是最後那個true,它告訴wpf引擎相應元素call這個handle,即使它被標記為handled=true。但是元素處理後其上層元素也照樣不會相應,因為handle仍被標記已處理。由此可見,wpf路由事件被標記為handled以後,並不是不在visual tree上傳遞了;而是,不去call這個handler了

上例中如果想要usercontrol繼續響應,處境就與1一樣了,只需將handle標記為false即可。

引用博文:

onActivityResult 標記為已過時

onactivityresult 雖然標記為已過時 不過暫時還可以使用 onactivityresult 已經標記為已過時 點選super.onactivityresult檢視原始碼,可以看見官方已經給了新的使用替換方式 使用registerforactivityresult 方法 注意是乙個fin...

WPF捕獲事件即使這個事件被標記為Handled

前面的博文 wpf拖動總結 中debuglzq遇到的問題是 debuglzq給容器中所有ui控制項註冊乙個mouseleftbutton事件,button控制項無法捕獲這兒事件的問題,加個斷點看下,程式根本不到達這個地方。當時只是簡短的提了一下,覺得不夠,因此決定再發一篇博文來說一下。foreach...

WPF捕獲事件即使這個事件被標記為Handled

前面的博文 wpf拖動總結 中debuglzq遇到的問題是 debuglzq給容器中所有ui控制項註冊乙個mouseleftbutton事件,button控制項無法捕獲這兒事件的問題,加個斷點看下,程式根本不到達這個地方。當時只是簡短的提了一下,覺得不夠,因此決定再發一篇博文來說一下。foreach...