我的场景被简化了:我有一个包含多行员工的 ListView,在每一行员工中,都有“增加”和“减少”按钮来调整他的薪水。
假设在我的程序中,双击 Employee 行表示“解雇此人”。
问题 是当我快速单击“增加”时,这会触发 ListViewItem 上的双击事件。自然地,我不想在只是增加薪水时解雇他们。
根据所有其他事件的工作方式,我希望能够通过在事件上设置 Handled=true
来解决这个问题。但是,这不起作用。在我看来,WPF 生成两个独立的、完全未链接的双击事件。
以下是重现我的问题的最小示例。可见组件:
<ListView>
<ListViewItem MouseDoubleClick="ListViewItem_MouseDoubleClick">
<Button MouseDoubleClick="Button_MouseDoubleClick"/>
</ListViewItem>
</ListView>
处理程序代码:
private void Button_MouseDoubleClick(object s, MouseButtonEventArgs e) {
if (!e.Handled) MessageBox.Show("Button got unhandled doubleclick.");
e.Handled = true;
}
private void ListViewItem_MouseDoubleClick(object s, MouseButtonEventArgs e) {
if (!e.Handled) MessageBox.Show("ListViewItem got unhandled doubleclick.");
e.Handled = true;
}
启动该程序并双击列出的按钮后,两个 消息框依次显示。 (此外,此后按钮卡在向下位置。)
作为“修复”,我可以在 ListViewItem 处理程序上检查附加到事件的可视树并检查“某处有一个按钮”,从而丢弃该事件,但这是不得已的办法。我想至少在编写这样一个困惑的代码之前了解这个问题。
有谁知道为什么 WPF 这样做,以及避免该问题的优雅惯用方法?
最佳答案
我想您会发现 MouseDoubleClick
事件是 MouseDown
事件之上的抽象。也就是说,如果两个 MouseDown
事件足够快地连续发生,则 MouseDoubleClick
事件也会被引发。 Button
和 ListViewItem
似乎都具有此逻辑,因此这就解释了为什么您会看到两个不同的 MouseDoubleClick
事件。
根据 MSDN :
Although this routed event seems to follow a bubbling route through an element tree, it actually is a direct routed event that is raised along the element tree by each UIElement. If you set the Handled property to true in a MouseDoubleClick event handler, subsequent MouseDoubleClick events along the route will occur with Handled set to false.
您可以尝试在 Button
上处理 MouseDown
并将其设置为已处理,这样它就不会传播到 ListViewItem
。
希望我能自己验证这一点,但目前我还没有使用 .NET。
关于c# - MouseDoubleClick 事件不会冒泡,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6279724/