WPF中的MouseEnter和MouseLeave处理(使用VS2008和.net 3.5)未按预期工作

4
没有图片和代码的情况下很难解释问题。如果您感兴趣,我已经制作了一个示例C#/WPF项目,可以从http://rapidshare.com/files/461745095/02.WPFControlEvents.rar下载。
这是一个非常小的项目(45KB)。问题如下(对于曲折的描述,我表示歉意):
一个“花哨”(而且相当丑陋)的按钮包含一个堆栈面板,该面板依次包含1.)标签,2.)画布,3.)两个同心椭圆,所有这些都从左到右排列。
堆栈面板有一个MouseEnter和一个MouseLeave事件处理程序,用于在标题栏中显示消息,指示鼠标是否在堆栈面板上方或其外部。
问题是:当鼠标位于标签上时(转而包含在堆栈面板中),报告鼠标正在堆栈面板上方(正确)。当鼠标移动到画布上时(也包含在堆栈面板中),鼠标被错误地报告为未在堆栈面板上方,但是当鼠标稍微向右移动一点(在画布上的两个椭圆上),鼠标又被报告为在堆栈面板上方。
为什么当鼠标在画布上时,它被报告为不在堆栈面板上方,但是当鼠标位于椭圆上时(这些椭圆绘制在画布上),它被报告为在堆栈面板上方?
感谢您解决问题,
John.

1
我不知道为什么会出现这种情况,但一个实用的解决方法可能是使用网格来布置标签和椭圆对象,使用Margin属性来定位两个椭圆。这避免了嵌套容器可能导致的行为问题。 - Dan Bryant
@Dan:我尝试了你的建议。使用网格并没有出现问题,即使画布的背景没有设置为透明(如CodeNaked下面建议的那样)。谢谢。 - Hex440bx
任何可能阅读此内容以理解/解决相同问题的人:仅更改为网格似乎已经解决了问题,因为它使标签占据了网格的整个宽度。 标签是可点击的,并且遮罩在画布上方,掩盖了问题的持续存在。请参见CodeNaked的最后(或接近最后)评论,以获得更好和更完整的解释。 - Hex440bx
1
只是为了明确,我的建议是完全消除Canvas,而是在Grid中的第二列放置Ellipses。您可以使用Margin属性将它们放置在Grid单元格中,这顺便为按钮的缩放提供了更好的支持。正因为如此,我现在很少使用Canvas容器。 - Dan Bryant
@Dan:我明白了。在我的测试中,我仍然使用了Canvas,这是问题的根源。如果我完全消除Canvas并用Grid替换它,一切都会像你建议的那样正常工作。感谢您指出了更清晰的方法。 - Hex440bx
1个回答

2

很可能你需要将画布的背景设置为透明。这样可以使其可“命中测试”,并报告鼠标悬停事件。

更多信息可以在此处找到,但是Canvas默认具有空背景。


@CodeNaked:这是一个很好的建议。将背景设置为透明后,问题得到了解决。我仍然想了解原始行为的原因,因为对我来说,当鼠标位于椭圆形上(它们不是透明的)时,鼠标被报告为在堆栈面板上,但当鼠标位于未绘制的画布上时,则不会如此,这一点对我来说没有意义。 - Hex440bx
1
@Hex440bx - 上面的链接里已经有一些解释了,但是拥有 null 背景有点像将 IsHitTestVisible 设置为 false。不同之处在于 IsHitTestVisible 影响任何后代(比如你的椭圆),而使用 null 背景只影响该对象本身(比如你的 Canvas)。因此,如果鼠标位于一个椭圆上方,则其任何祖先都会将 IsMouseOver 设置为 true。当鼠标移到 Canvas 上时,它不会“接收”任何关于“null 像素”的鼠标事件,因此祖先不会将 IsMouseOver 设置为 true。 - CodeNaked
@Hex440bx - 只要它们的背景都设置为 null,它们是 Grid 还是 StackPanel 就无关紧要。如果您可以发布一些 XAML 代码,我可以仔细查看。 - CodeNaked
@CodeNaked:我只对我发布的项目中的xaml代码进行了两处更改。我将内部的stackpanel更改为grid,导致出现这样一行代码:<Grid MouseEnter="StackPanel_MouseEnter" MouseLeave="StackPanel_MouseLeave" Width="236">当然,我也将相应的闭合标签从</StackPanel>更改为</Grid>。这个更改解决了问题,即使Canvas背景仍然设置为null。 - Hex440bx
1
@Hex440bx - 如果您不设置Grid.Row或Grid.Column,则所有Grid子元素将堆叠在一起。此外,Label没有宽度,因此它将被拉伸以水平填充Grid。因此,在技术上,您可以删除Canvas并看到相同的行为,因为命中测试落在Label而不是Canvas上。 - CodeNaked
显示剩余5条评论

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