3

我的表单层次结构是这样的:

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”。我的代码哪里出错了?谢谢。

4

2 回答 2

9

GetChildFromPoint()方法使用本机ChildWindowFromPointEx()方法,其文档说明:

确定属于指定父窗口的子窗口中的哪个(如果有)包含指定点。该函数可以忽略不可见、禁用和透明的子窗口。搜索仅限于直接子窗口。不搜索孙子和更深的后代。

请注意粗体文本:该方法无法得到您想要的。

理论上你可以调用GetChildFromPoint()返回的控件,直到你得到null

Control crp = this.GetChildAtPoint(cursosPosition2);
Control lastCrp = crp;

while (crp != null)
{
    lastCrp = crp;
    crp = crp.GetChildAtPoint(cursorPosition2);
}

然后你就会知道那lastCrp是那个位置上最低的后代。

于 2011-09-22T02:52:19.507 回答
3

更好的代码可以写成如下:

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);
于 2018-09-26T05:54:49.547 回答