在MSDN文章" 了解WPF中的路由事件和命令"中,它说明了这一点
事件将从源元素向上冒泡(传播)可视树,直到它被处理或到达根元素.
但是,在此示例中,当您单击按钮时,它不会"冒泡可视树"以由父StackPanel事件处理,即单击按钮不会触发任何事件.
为什么不?如果不是这样的话,他们是什么意思"冒泡"?
XAML:
后台代码:
using System.Windows; using System.Windows.Input; namespace TestClickEvents456 { public partial class Window1 : Window { public Window1() { InitializeComponent(); } private void TheStackPanel_MouseDown(object sender, MouseButtonEventArgs e) { TheMessage.Text = "StackPanel was clicked."; } } }
Arcturus.. 25
事件冒出来,直到它被处理完毕......
由于Button通过鼠标点击执行某些操作,因此它会吸收鼠标事件并将其转换为ClickEvent.
如果您使用PreviewMouseDown,您会看到StackPanel首先在按钮之前接收到该事件.预览事件使用隧道向下方法.
事件冒出来,直到它被处理完毕......
由于Button通过鼠标点击执行某些操作,因此它会吸收鼠标事件并将其转换为ClickEvent.
如果您使用PreviewMouseDown,您会看到StackPanel首先在按钮之前接收到该事件.预览事件使用隧道向下方法.
正如其他人所说,这是因为MouseDown
事件在Button
被进一步冒泡之前就被处理了.您可以在Reflector中看到ButtonBase.OnMouseLeftButtonDown
:
protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e) { if (this.ClickMode != ClickMode.Hover) { e.Handled = true; // SNIP... } base.OnMouseLeftButtonDown(e); }
一种解决方案是监听MouseDown
事件,并指出您不关心事件是否得到处理.您可以使用该AddHandler
方法执行此操作.它有一个布尔重载,可以让你监听已经处理过的事件.
如果您在某处执行此操作而不是在XAML中设置MouseDown处理程序:
TheStackPanel.AddHandler(MouseDownEvent, new MouseButtonEventHandler(TheStackPanel_MouseDown), true);
无论是否已经处理,您都将收到所有MouseDown
活动TheStackPanel
.
此外,如果您希望stackpanel接收事件,请将stackpanel xaml更改为:
和事件签名:
private void TheStackPanel_MouseDown(object sender, RoutedEventArgs e)
在这种情况下,stackpanel将接收按钮的单击事件.但是,单击stackpanel本身不会触发任何事件,因为它专门监听按钮单击.