1.見鬼了?
項目中遇到這樣的要求,一個Button用一個Adorner裝飾,這個Adorner上又有一個Button,如下面這樣
此時,我們在點擊小Button的時候只希望處理小Button的事件,可是這時候,居然大Button的事件也觸發了。按道理上講,Adorner和Button不在可視化樹的一個層次上,即使冒泡也不可能冒到另一個分支上呀?這不科學呀,於是乎見鬼了~~。
2.小心求證
於是乎自己做了一個簡單的Demo,怕因為工程中干擾因素太多導致的bug,可是!居然還是發生了!這個bug卡我一個星期你信不?還是直說吧,畢竟也不是很嚴重的問題。
我們要放置其他控件到Adorner上,就需要Adorner有一個容器可以容納,一般我喜歡用VisualCollection
public NotifyAdorner(UIElement adornedElement) : base(adornedElement) { _visuals = new VisualCollection(adornedElement); }
adornerElement就是被裝飾的UI元素,我們用它來初始化了VisualCollection,而細看VisualCollection的參數,表示一個父級~~,那么問題就很明顯了,雖然我們在Adorner上有小Button,但是它卻是屬於大Button內的可視化元素,那么點擊小Button,冒泡到父級同樣要觸發事件,好,現在我們把小Button的按鈕事件加上e.Handled=true,果然,大Button事件沒有調用。修改Adorner如下
public NotifyAdorner(UIElement adornedElement) : base(adornedElement) { _visuals = new VisualCollection(this); }
這樣,就正確了。
另外一個就是,有時候不得以需要和被裝飾的元素交互,但礙於上層有一個Adorner(完全擋住),這個時候就可以使用以下這種思路。
Demo:https://git.oschina.net/HelloMyWorld/AdornerSample.git