我正在尝试在 Windows 窗体应用程序上进行智能控制。
首先是一个普通按钮(“大按钮”)。在 MouseHover
上,它会隐藏自己,同时会出现一个面板。面板内部有四个小按钮。它们各自代表一个“快速行动”。当鼠标离开面板时,大按钮应该出现,面板本身应该隐藏。
面板
面板是一个普通的用户控件。它包含四个带边框的普通按钮(嵌套按钮)。
它仅在鼠标悬停在面板上时可见。
大按钮
大按钮只是一个普通按钮。它是可见的(并且可以点击),但只有在 MouseHover
事件未被触发时才会出现。
问题
问题是我无法捕获面板
的MouseLeave
事件。这是因为它里面有嵌套按钮,这意味着每次鼠标移到嵌套按钮上时,面板
的MouseLeave
事件都会被触发。
一种方法
我试图通过实现嵌套按钮
和面板
的MouseLeave
事件来防止这种情况发生。每次触发 MouseLeave
事件时,我都会检查鼠标是否仍在 面板
的矩形内。
漏洞
上一段中描述的方法效果不错,但有一个问题。每次鼠标越过边界(主要是嵌套按钮
)时,MouseLeave
事件捕获的MousePosition
都是错误的。通常它在一个消极和随机的地方。
我使用以下代码检查 MousePosition
:
panelRectangle.Contains(PointToClient(MousePosition))
(MousePosition
是从窗体的角度来看的,但这并不能解释为什么有时位置为负,如果嵌套按钮位于窗体的中间)。
问题
如何查看鼠标是否在面板内?主要问题是边界。当鼠标位于嵌套按钮的边框上时,为什么我的 MousePosition
位于随机位置?
这是一些其他代码:
bool bInsideRectangle =
Rectangle panelRectangle = new Rectangle(this.panelContainer.Location, this.panelContainer.Size);
if (panelRectangle.Contains(PointToClient(Control.MousePosition)) || PointToClient(Control.MousePosition).X < 0 || PointToClient(Control.MousePosition).Y < 0)
{
bInsideRectangle = true;
}
//bool bIsInsideOfPanel = this.panelContainer.ClientRectangle.Contains(PointToClient(Control.MousePosition));
//bool bIsInsideOfButton1 = this.button1.ClientRectangle.Contains(PointToClient(Control.MousePosition));
//bool bIsInsideOfButton2 = this.button2.ClientRectangle.Contains(PointToClient(Control.MousePosition));
//bool bIsInsideOfButton3 = this.button3.ClientRectangle.Contains(PointToClient(Control.MousePosition));
//bool bIsInsideOfButton4 = this.button4.ClientRectangle.Contains(PointToClient(Control.MousePosition));
// Check if the mouse is not inside of those child-controls.
if(!bInsideRectangle)
//if (!bIsInsideOfPanel && !bIsInsideOfButton1 && !bIsInsideOfButton2 && !bIsInsideOfButton3 && !bIsInsideOfButton4)
{
this.panelContainer.Visible = false;
this.buttonBig.Visible = true;
}
最佳答案
创建一个小助手,告诉您鼠标是否在控件的边界内
// The helper relies on "MousePosition" member of the form
// so this function has to be in the form, or you find another way to do the check
bool isMouseInControl(Control control)
{
return control.ClientRectangle.Contains(control.PointToClient(MousePosition));
}
现在将 MouseEnter 和 MouseLeave 绑定(bind)到你的大按钮
bigButton.MouseEnter += bigButton_MouseEnter;
bigButton.MouseLeave += bigButton_MouseLeave;
记住子菜单的当前状态 (bool) bool submenu = false;
现在您可以像这样检查正确的离开/进入:
void bigButton_MouseLeave(object sender, EventArgs e)
{
if(submenu && !isMouseInControl(sender as Control))
{
submenu = false;
// Disable submenu here
}
}
void bigButton_MouseEnter(object sender, EventArgs e)
{
if(submenu || isMouseInControl(sender as Control))
{
submenu = true;
// Enable submenu here
}
}
bool submenu
是可选的,因为它只在不需要时阻止检查(据我所知,它只对 mouseenter 起作用...)
关于C# 关于边界和行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24183219/