【发布时间】:2010-02-05 23:08:36
【问题描述】:
我有一个用于 Panel 控件的 mouseenter 和 mouseleave 事件,当鼠标进入时改变背景颜色,离开时返回白色。
我在这个面板中也有 Label 控件,但是当鼠标进入 Label 控件时,会触发面板的 mouseleave 事件。
这是有道理的,但是当鼠标在其区域中时,如何保持面板的背景颜色相同,而内部的其他控件不会影响它?
【问题讨论】:
我有一个用于 Panel 控件的 mouseenter 和 mouseleave 事件,当鼠标进入时改变背景颜色,离开时返回白色。
我在这个面板中也有 Label 控件,但是当鼠标进入 Label 控件时,会触发面板的 mouseleave 事件。
这是有道理的,但是当鼠标在其区域中时,如何保持面板的背景颜色相同,而内部的其他控件不会影响它?
【问题讨论】:
您可以使用 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;
}
}
【讨论】:
我找到了一个简单的解决方案。我只是在标签上将 enabled 属性设置为 false 就可以了。
【讨论】:
为包含的控件添加事件意味着当您想向面板添加另一个控件时,您也必须为此进行相同的练习。
为父控件添加一个事件意味着一旦你想在其他地方使用面板,你必须为新的父控件做同样的事情。而且当面板的需求发生变化时,你要记得把处理从父控件的事件中拿出来。
所有这些都可能会更进一步。
我倾向于在面板的鼠标离开事件中进行一些坐标检查,并且仅在鼠标确实超出面板边界时才重置面板颜色。
这样,您的面板处理代码仅保留在相关面板上。
【讨论】:
您可以为标签添加一个 MouseEnter 事件,该事件也设置面板的背景颜色。标签不需要 MouseLeave 事件。
或者:
如果您想在不接触父控件代码的情况下执行上述第 2 点(根据其他用户的评论),您可以在 Panel 的 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; };
}
}
【讨论】: