WPF - 判断鼠标是否悬停在UI元素上

13

我有一些 XAML 标记语言,看起来基本上像这样:

<Canvas x:Name="A">
     <Canvas x:Name="B"/>
</Canvas>

我想确定鼠标是否悬停在Canvas B上。

当我的鼠标悬停在Canvas B上时单击,鼠标的DirectlyOver返回Canvas A(正如我所预期)。然后我从Canvas A获取对Canvas B的引用,但是当我检查Canvas B的IsMouseOver属性时,它返回false。

在给定上述xaml的情况下,最佳方法是什么来确定鼠标是否悬停在Canvas B上?


你使用了哪种事件处理来进行检查?如果我在画布B上添加一个MouseUp事件,那么Mouse.DirectlyOver将返回Canvas B。也许提供更多信息可以帮助我们找到问题的根源。 - Liz
当然。Canvas实际上是在ListBoxItem的ControlTemplate中。我正在处理listbox的selection changed事件,并执行一个路由事件来显示有关所单击项的详细信息的弹出窗口。我检查鼠标所在位置的代码位于路由事件处理程序中。所有这些的目标是在单击列表项的右侧部分时不显示弹出窗口。因此,我尝试使用canvas定义列表项的该部分,然后检查鼠标是否悬停在该部分上,然后再显示弹出窗口。 - Brent Lamborn
我知道还有其他方法可以做到这一点,但我试图避免使用除选择更改事件之外的任何东西。 - Brent Lamborn
3个回答

39
你可以使用IsMouseOver属性来确定鼠标是否在给定的控件上方:
if(this.B.IsMouseOver)
    DoSomethingNice();

虽然Mouse.DirectlyOver可以使用,但如果鼠标位于Canvas中包含的控件上方,则返回该控件而不是Canvas本身。在这种情况下,IsMouseOver将正常工作。


3
请注意,在拖放操作期间,您将需要手动检测“IsMouseOver”和“DirectlyOver”,因为鼠标被捕获直到拖放完成。对于那些不知道的人,可以通过检查鼠标是否在控件边界内来完成“IsMouseOver”,并使用“VisualTreeHelper.HitTest”来完成“DirectlyOver”。 - Koby Duck
如果我想要在一个非常大的控件上方精确定位,该怎么办? - John Demetriou

4
我在StackOverflow上找到了一个答案,应该可以帮助您:StackOverflow: WPF Ways to find controls 仅供参考:
我只是在寻找一种方法来查找我的鼠标是否在我的应用程序窗口中,我成功地使用以下方法找到了这个问题:
if (Mouse.DirectlyOver != null)
    DoSomethingNice();

在调试Mouse.DirectlyOver时,它似乎应该找到您的Canvas B,因为它正在查找最上层的元素 - 所以您的示例应该可以工作。它没有给我一个依赖对象,但我想你可以在代码后端使用这个来将其与你的画布进行比较(未经测试):

if (Mouse.DirectlyOver == this.B)
    DoSomethingNice();

1

在这里,您可以找到与命中测试相关的鼠标点击事件。

{
            Point pt = e.GetPosition((UIElement)sender);

            // Perform the hit test against a given portion of the visual object tree.
            HitTestResult result = VisualTreeHelper.HitTest(this.B, pt);

            if (result != null)
            {
                // Perform action on hit visual object.              
            }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接