我正在搜索一个属性,该属性为我提供了一个相对于Form的位置的Control位置,而不是Form ClientRectangle's
“0,0”。
当然我可以将所有内容转换为屏幕坐标,但我想知道是否有更直接的方法来做到这一点。
答案 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;
}