我有一个包含子控件的Panel
。
如果我处理Panel
的{{1}}和MouseEnter
事件及其子项的MouseLeave
和MouseEnter
事件,则会按此顺序引发事件:
MouseLeave
但我需要以下顺序:
Panel.MouseEnter
Panel.MouseLeave
Child1.MouseEnter
Child1.MouseLeave
Panel.MouseEnter
Panel.MouseLeave
这可能吗?
答案 0 :(得分:21)
如果你不介意创建一个usercontrol(派生自你想要的面板或其他父容器),
覆盖父项的OnMouseLeave
方法,如下所示..
protected override void OnMouseLeave(EventArgs e)
{
if(this.ClientRectangle.Contains(this.PointToClient(Control.MousePosition)))
return;
else
{
base.OnMouseLeave(e);
}
}
然后,事件提升将按所需顺序进行。
答案 1 :(得分:5)
鼠标在进入子控件时“离开”面板,这就是它触发事件的原因。
您可以在面板MouseLeave
事件处理程序中添加以下行中的内容:
// Check if really leaving the panel
if (Cursor.Position.X < Location.X ||
Cursor.Position.Y < Location.Y ||
Cursor.Position.X > Location.X + Width - 1 ||
Cursor.Position.Y > Location.Y + Height - 1)
{
// Do the panel mouse leave code
}
答案 2 :(得分:2)
解决方案是跟踪进入/离开的数量。 在你的整体控制中添加一个计数器:
private int mouseEnterCount = 0;
在MouseEnter处理程序中执行以下操作:
if (++mouseEnterCount == 1)
{
// do whatever needs to be done when it first enters the control.
}
在MouseLeave处理程序中执行以下操作:
if (--mouseEnterCount == 0)
{
// do whatever needs to be done when it finally leaves the control.
}
为所有子控件以及包含对象执行上述MouseEnter和MouseLeave事件处理程序。
答案 3 :(得分:2)
马修的答案永远不会奏效。特别是如果将子控件设置为其容器的边缘,并且鼠标在该方向上移出控件。您永远不会检测到MouseLeave事件。
最好的方法是创建一个用户控件容器,然后挂钩所有子控件的MouseEnter和MouseLeave事件,以便您可以随时正确地检测鼠标的位置和位置。那么,如果它进入容器的边界,你可以触发一个自定义的MouseEnter事件,当它离开MouseLeave事件时。
答案 4 :(得分:1)
答案 5 :(得分:0)
我相信。用于验证WinForms应用程序事件的好工具。
http://missico.spaces.live.com/blog/cns!7178D2C79BA0A7E3!186.entry
答案 6 :(得分:0)
这是一个棘手的问题,并且难以可靠地编码。一个想法是“捕获”列表中的3个传入事件,并在列表完成后执行所需的代码(列表中有3个所需事件)。然后,当您完成执行任何代码(或者可能反过来捕获事件组合)时,您可以清空列表并准备好下次特定组合事件发生时。不理想,但只是一个想法。
当然,这并没有克服潜在的解决问题。汉斯提出可能错过的事件。也许更多的背景是有序的。
答案 7 :(得分:0)
检查子组件..
if (panel1.GetChildAtPoint(panel1.PointToClient(Cursor.Position)) == null)
{
// mouse leave panel and children
}
答案 8 :(得分:0)
Jimmy T.是对的。如果父控制(面板)边缘和儿童控制之间没有(或小)空间,则会出现问题。
这就是我在UserControl派生类中解决这个问题的方法:
public CSStackPanelItem()
{
InitializeComponent();
MouseEnter += new EventHandler(CSStackPanelItem_MouseEnter);
foreach (Control child in Controls)
{
child.MouseEnter += (s, e) => CSStackPanelItem_MouseEnter(s, e);
child.MouseLeave += (s, e) => OnMouseLeave(e);
}
}
protected override void OnMouseLeave(EventArgs e)
{
if (this.ClientRectangle.Contains(this.PointToClient(Control.MousePosition)))
return; //suppress mouse leave event handling
if (m_bIsHover)
{
m_bIsHover = false;
Invalidate(); //actually my mouse Enter/Leave event
}
base.OnMouseLeave(e);
}
void CSStackPanelItem_MouseEnter(object sender, EventArgs e)
{
m_bIsHover = true;
Invalidate(); //actually my mouse Enter/Leave event
}
答案 9 :(得分:0)
我的解决方案是为面板和该面板的父窗体创建一个 MouseEnter
事件。我不参与任何 MouseLeaving
事件。
当光标进入面板时,MouseEnter
会触发。我可以访问所有面板子控件,但没有任何反应(这是我想要的)。当我离开面板时,父表单的 MouseEnter
会触发。