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(完全挡住),这个时候就可以使用以下这种思路。