我的表单层次结构是这样的:
Form -> TableLayoutOne -> TableLayoutTwo -> Panel -> ListBox
在ListBox的MouseMove事件中,我有这样的代码:
Point cursosPosition2 = PointToClient(new Point(Cursor.Position.X, Cursor.Position.Y));
Control crp = this.GetChildAtPoint(cursosPosition2);
if (crp != null)
MessageBox.Show(crp.Name);
MessageBox向我显示“TableLayoutOne”,但我希望它向我显示“ListBox”。我的代码在哪里,我错了?感谢。
答案 0 :(得分:7)
GetChildFromPoint()
方法使用原生ChildWindowFromPointEx()
方法,其文档说明:
确定属于哪个子窗口的子窗口(如果有) 指定的父窗口包含指定的点。功能可以 忽略不可见,禁用和透明的子窗口。 搜索 仅限于直接的儿童窗户。孙子孙女更深 未搜索后代。
请注意粗体文字:该方法无法获得您想要的效果。
理论上,您可以在返回的控件上调用GetChildFromPoint()
,直到获得null
:
Control crp = this.GetChildAtPoint(cursosPosition2);
Control lastCrp = crp;
while (crp != null)
{
lastCrp = crp;
crp = crp.GetChildAtPoint(cursorPosition2);
}
然后你知道lastCrp
是那个位置的最低后代。
答案 1 :(得分:1)
更好的代码可以编写如下:
Public Control FindControlAtScreenPosition(Form form, Point p)
{
if (!form.Bounds.Contains(p)) return null; //not inside the form
Control c = form, c1 = null;
while (c != null)
{
c1 = c;
c = c.GetChildAtPoint(c.PointToClient(p), GetChildAtPointSkip.Invisible | GetChildAtPointSkip.Transparent); //,GetChildAtPointSkip.Invisible
}
return c1;
}
用法如下:
Control c = FindControlAtScreenPosition(this, Cursor.Position);