C# Windows Forms中的自定义控件鼠标事件问题

5

我有一个Panel控件的mouseenter和mouseleave事件,当鼠标进入时更改背景颜色,当鼠标离开时返回白色。

我还在这个面板中添加了一个Label控件,但当鼠标进入Label控件时,会触发Panel的mouseleave事件。

这很合理,但我该如何在鼠标停留在Panel区域内时保持Panel的背景颜色不变,而不受其中其他控件的影响呢?

4个回答

6
您可以使用GetChildAtPoint()方法来确定鼠标是否悬停在子控件上。
private void panel1_MouseLeave(object sender, EventArgs e)
{
    if (panel1.GetChildAtPoint(panel1.PointToClient(MousePosition)) == null)
    {
        panel1.BackColor = Color.Gray;
    }
}

如果控件实际上不是子控件,你仍然可以使用MousePosition和PointToScreen来确定鼠标是否仍在控件的边界内。
private void panel1_MouseLeave(object sender, EventArgs e)
{
    Rectangle screenBounds = new Rectangle(this.PointToScreen(panel1.Location), panel1.Size);
    if (!screenBounds.Contains(MousePosition))
    {
        panel1.BackColor = Color.Gray;
    }
}

正是我所需要的,包括更改面板背景颜色的原因,也是出于同样的原因。谢谢! - Jon Burchel

2
我找到了一个简单的解决方案。我只需将标签的enabled属性设置为false,就可以了。

4
直到你想在面板上启用控制,否则一切都会很好 :) - ChrisA
不错的简单解决方案!也帮助了我解决我的特定问题。不过,如果有一种设置父控件以预览鼠标事件的方法,在它们发送到子控件之前,那就太好了。 - Andy

1

为包含的控件添加事件意味着当您想要将另一个控件添加到面板时,您也必须进行相同的操作。

为父控件添加事件意味着一旦您想在其他地方使用面板,您必须为新的父控件做同样的事情。当面板的要求发生变化时,您必须记住将处理从父控件的事件中移除。

这些都可能会在稍后变得有点混乱。

我倾向于在面板的鼠标离开事件中放置一些坐标检查,并且仅当鼠标真正超出面板的边界时才重置面板颜色。

这样,您处理面板的代码仅适用于相关的面板。


0
你可以为标签添加一个MouseEnter事件,该事件还设置了面板的背景颜色。您不需要为标签添加MouseLeave事件。
或者:
1. 为面板设置MouseEnter事件以设置面板的背景颜色。 2. 设置面板父控件(例如Form)的MouseEnter事件以重置面板的背景颜色。
如果您想在不触及父控件代码的情况下执行上述第2点(根据其他用户的评论),您可以在面板的ParentChanged事件中执行以下操作:
    private void panel1_ParentChanged(object sender, EventArgs e)
    {
        Panel thisPanel = sender as Panel;

        if(thisPanel != null && thisPanel.Parent != null)
        {
            thisPanel.Parent.MouseEnter += delegate(object senderObj, EventArgs eArgs) { thisPanel.BackColor = SystemColors.Control; };
        }
    }

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