我在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}。
这些数字会直接计算并打印到调试窗口,而不会移动任何东西......疯狂。
好吧,这变得相当混乱,但我仍然希望有人有一个简单的解释。谢谢!答案 0 :(得分:3)
好的,我找到了解决方案。
在创建控件之前,我碰巧调用了Control.PointToScreen :Control.IsHandleCreated = False。
如果我确保首先创建控件(Control.CreateControl),则两种方法都可以正常工作。
我在后续调用中得到不同结果的原因是第一次调用Control.PointToScreen也会导致创建控件(因此它的父节点和父节点上的任何其他控件),这意味着第二次成功。
嗯,我很高兴能够做到这一点: - )
答案 1 :(得分:0)
我认为这是睡眠。 :)而不是:
ctl.PointToScreen(Point.Empty)
ctl.Parent.PointToScreen(ctl.Location)
尝试:
相反,你会看到x / y坐标的差异。ctl.PointToScreen(Point.Empty)
ctl.PointToScreen(ctl.Location)//注意没有.Parent!
此外,在执行PointToScreen数学运算时,尝试使用Control.TopLevelControl或Control.FindForm()来获取最外层的Form。