Vb.net 相对于窗体或屏幕定位UserControl

Vb.net 相对于窗体或屏幕定位UserControl,vb.net,winforms,user-controls,location,Vb.net,Winforms,User Controls,Location,有没有办法获取和设置用户控件的位置,该控件位于容器(例如面板)上,相对于“最亲”窗体 我知道可以计算面板本身的偏移量,并将其添加到用户控件的位置 但在我的例子中,父级别的数量是未知的,并且可能因情况而异。 因此,一旦用户控件可以放置在面板上,该面板直接位于表单上。但是也有可能用户控件被放置在第二个面板上,该面板位于表单上的第一个面板,如果您将计算面板偏移量的想法重新计算回表单,会怎么样?i、 e.我在一个面板中有一个文本框1,在一个面板1中有一个文本框2。面板1位于左侧266,面板2位于面板1内

有没有办法获取和设置
用户控件的
位置
,该控件位于
容器
(例如
面板
)上,相对于“最亲”窗体

我知道可以计算
面板
本身的偏移量,并将其添加到
用户控件
位置

但在我的例子中,父级别的数量是未知的,并且可能因情况而异。
因此,一旦
用户控件
可以放置在
面板
上,该面板直接位于
表单
上。但是也有可能
用户控件
被放置在第二个
面板
上,该面板位于
表单
上的第一个
面板
,如果您将计算面板偏移量的想法重新计算回表单,会怎么样?i、 e.我在一个面板中有一个文本框1,在一个面板1中有一个文本框2。面板1位于左侧266,面板2位于面板1内的左侧77

Private Function GetLeftOffset(ByVal UserControl As Control) As Int32
    Dim intLeftOffset As Int32 = 0
    If Not TypeOf UserControl.Parent Is Form Then
        intLeftOffset = UserControl.Parent.Left
        intLeftOffset += GetLeftOffset(UserControl.Parent)
    End If
    Return intLeftOffset
End Function

现在,如果我获取leftOffset(Me.TextBox1),它将返回一个343(266+77)的偏移量。

如果您考虑计算面板的偏移量,然后递归地将偏移量计算回表单,会怎么样?i、 e.我在一个面板中有一个文本框1,在一个面板1中有一个文本框2。面板1位于左侧266,面板2位于面板1内的左侧77

Private Function GetLeftOffset(ByVal UserControl As Control) As Int32
    Dim intLeftOffset As Int32 = 0
    If Not TypeOf UserControl.Parent Is Form Then
        intLeftOffset = UserControl.Parent.Left
        intLeftOffset += GetLeftOffset(UserControl.Parent)
    End If
    Return intLeftOffset
End Function
现在,如果我获取leftOffset(Me.TextBox1),它将返回343(266+77)的偏移量。

尝试:

Dim pnt As Point

pnt = UserControl.PointToScreen(New Point(0, 0))
pnt = Me.PointToClient(pnt)
这将计算相对于表单的位置。如果你愿意的话,把我换成任何控制

现在,如果您想设置相对于表单的位置,例如(100100)

请记住,如果新位置在父区域之外,控件将不可见。

请尝试:

Dim pnt As Point

pnt = UserControl.PointToScreen(New Point(0, 0))
pnt = Me.PointToClient(pnt)
这将计算相对于表单的位置。如果你愿意的话,把我换成任何控制

现在,如果您想设置相对于表单的位置,例如(100100)


请记住,如果新位置在父区域之外,控件将不可见。

我使用此功能在控件附近放置上下文菜单,如文本框或按钮。可以将x和y设置为零以返回控件本身的位置

'--- Return the screen location of a control with an offset

Private Function Offset(ByRef controlObj As Control, ByVal x As Integer, ByVal y As Integer) As Point

  Dim pt As Point
  Dim parentObj As Control = controlObj.Parent

  Do While parentObj IsNot controlObj.FindForm
    x += parentObj.Location.X
    y += parentObj.Location.Y
    parentObj = parentObj.Parent
  Loop

  pt = PointToScreen(controlObj.Location)
  pt.Offset(x, y)
  Return pt

End Function

我使用此函数在控件(如文本框或按钮)附近放置上下文菜单。可以将x和y设置为零以返回控件本身的位置

'--- Return the screen location of a control with an offset

Private Function Offset(ByRef controlObj As Control, ByVal x As Integer, ByVal y As Integer) As Point

  Dim pt As Point
  Dim parentObj As Control = controlObj.Parent

  Do While parentObj IsNot controlObj.FindForm
    x += parentObj.Location.X
    y += parentObj.Location.Y
    parentObj = parentObj.Parent
  Loop

  pt = PointToScreen(controlObj.Location)
  pt.Offset(x, y)
  Return pt

End Function

你知道哪一种解决方案在性能方面更好吗,你的还是卡佩兰的?@mookey如果你两个都打几次电话,没有明显的区别。但是如果你每秒多次调用它们,可能是我的,因为我使用的是本机函数。不过你必须测试一下才能确定。你知道哪种解决方案在性能方面更好吗,你的还是卡普兰的?@mookey如果你两个都打几次电话,没有明显的区别。但是如果你每秒多次调用它们,可能是我的,因为我使用的是本机函数。你必须测试它,我发现这是最有用的。还要注意父项的填充。我发现这是最有用的。还要注意父项的填充。