如何获得控件相对于Form的位置的位置?

时间:2012-04-19 20:38:59

标签: c# winforms

我正在搜索一个属性,该属性为我提供了一个相对于Form的位置的Control位置,而不是Form ClientRectangle's“0,0”。

当然我可以将所有内容转换为屏幕坐标,但我想知道是否有更直接的方法来做到这一点。

5 个答案:

答案 0 :(得分:10)

您需要转换为屏幕坐标,然后进行一些数学运算。

Point controlLoc = form.PointToScreen(myControl.Location);

表单的位置已经在屏幕坐标中。

现在:

Point relativeLoc = new Point(controlLoc.X - form.Location.X, controlLoc.Y - form.Location.Y);

这将为您提供相对于表单左上角的位置,而不是相对于表单的客户区域。

答案 1 :(得分:5)

我认为这会回答你的问题。注意"这个"是形式。

Rectangle screenCoordinates = control.Parent.ClientToScreen(control.ClientRectangle);
Rectangle formCoordinates = this.ScreenToClient(screenCoordinates);

答案 2 :(得分:3)

似乎答案是没有直接的方法来做到这一点。

(正如我在问题中所述,我正在寻找其他的方式,而不是使用屏幕坐标。)

答案 3 :(得分:1)

根据问题的具体情况,所选答案在技术上是正确的:.NET框架中不存在这样的属性。

但是如果你想要这样的属性,这里有一个控制扩展,可以解决这个问题。是的,它使用屏幕坐标,但考虑到帖子标题的一般性质,我确信登陆此页面的一些用户可能会觉得这很有用。

顺便说一句,我花了几个小时尝试通过循环遍历所有控制父项而没有屏幕坐标。我永远无法让这两种方法得到调和。这很可能是由于Hans Passant对OP的评论Aero关于窗口尺寸的看法。

using System;
using System.Drawing;
using System.Windows.Forms;

namespace Cambia
{
    public static class ControlExtensions
    {
        public static Point FormRelativeLocation(this Control control, Form form = null)
        {
            if (form == null)
            {
                form = control.FindForm();
                if (form == null)
                {
                    throw new Exception("Form not found.");
                }
            }

            Point cScreen = control.PointToScreen(control.Location);
            Point fScreen = form.Location;
            Point cFormRel = new Point(cScreen.X - fScreen.X, cScreen.Y - fScreen.Y);

            return cFormRel;

        }

    }
}

答案 4 :(得分:0)

当您将控件置于许多其他控件中且Autosize设置为true时,上述答案均无济于事。

Form -> FlowLayoutPanel -> Panel -> Panel -> Control

所以我用不同的逻辑编写了自己的代码,我只是不知道如果在父控件之间使用某些对接会产生什么结果。我猜这需要保证金和填充物介入。

    public static Point RelativeToForm(this Control control)
    {

        Form form = control.FindForm();
        if (form is null)
            return new Point(0, 0);

        Control parent = control.Parent;

        Point offset = control.Location;            

        while (parent != null)
        {
            offset.X += parent.Left;
            offset.Y += parent.Top;                
            parent = parent.Parent;
        }

        offset.X -= form.Left;
        offset.Y -= form.Top;

        return offset;

    }