Control.PointToScreen给出了不同的结果 - 为什么?

时间:2009-05-26 22:25:10

标签: c# vb.net winforms controls

我在Form上的Panel控件上有一些Label控件。我希望获得标签相对于表单原点的位置,以便在运行时我可以隐藏面板和标签,并将其他文本直接绘制到表单上。

基本上,我正在进行以下计算:使用Control.PointToScreen()获取标签的绝对屏幕位置,并使用Control.PointToClient()将其转换回相对位置,因此:

Dim newloc As Point = Me.PointToClient(ctl.PointToScreen(Point.Empty))

Dim newloc As Point = Me.PointToClient(ctl.Parent.PointToScreen(ctl.Location))

我发现这两种方法有时会给我不同的结果 - 将我的新观点带出负值的可见区域! - 但未能确定原因。我原以为它们应该是相同的(大部分时间都是这样)。

阅读文档并没有帮助第一次,但也许我跳过了一些东西......无论如何,在我开始撕掉头发之前,我会感谢任何帮助。

或者,另一方面,有更好的方法吗?

编辑:示例结果

所以,这是一个真实的例子。

Panel1上的{X = 4,Y = 6}处的<1> Label1;在同一父级Panel1上的{X = 163,Y = 6}处的Label2。显然我期待不同的X位置,但两者的Y应该是相同的。

当我运行项目时,

ctl.PointToScreen(Point.Empty)
ctl.Parent.PointToScreen(ctl.Location)
在{X = 959,Y = 119}时为Label1提供相同的屏幕位置(此处的绝对值可能会有所不同,当然,取决于表单本身的位置),因此当应用Me.PointToClient时,相对于表单的正确位置(在{X = 5,Y = 32}处)。

接下来的行对Label2执行相同的计算(记住,同一个Parent,父级(6)中的Y值相同),但结果完全关闭:ctl.Parent.PointToScreen()给了我{X = 1114,Y = 63}。 X几乎是正确的(959-4 + 163 = 1118),但Y远不及我为Label1获得的119。然后ctl.PointToScreen()给我{X = 166,Y = 29} - 转换回Form-Coordinates(Me.PointToClient){X = -784,Y = -2}。

这些数字会直接计算并打印到调试窗口,而不会移动任何东西......疯狂。

好吧,这变得相当混乱,但我仍然希望有人有一个简单的解释。谢谢!

2 个答案:

答案 0 :(得分:3)

好的,我找到了解决方案。

在创建控件之前,我碰巧调用了Control.PointToScreen :Control.IsHandleCreated = False。

如果我确保首先创建控件(Control.CreateControl),则两种方法都可以正常工作。

我在后续调用中得到不同结果的原因是第一次调用Control.PointToScreen也会导致创建控件(因此它的父节点和父节点上的任何其他控件),这意味着第二次成功。

嗯,我很高兴能够做到这一点: - )

答案 1 :(得分:0)

我认为这是睡眠。 :)而不是:

  

ctl.PointToScreen(Point.Empty)

     

ctl.Parent.PointToScreen(ctl.Location)

尝试:

  

ctl.PointToScreen(Point.Empty)

     

ctl.PointToScreen(ctl.Location)//注意没有.Parent!

相反,你会看到x / y坐标的差异。

此外,在执行PointToScreen数学运算时,尝试使用Control.TopLevelControl或Control.FindForm()来获取最外层的Form。