[2008] get a controls x/y relative to form
The .NET framework library is a big place. I am just wondering if anyone ever came across something in WinForms, that would allow you to get the x/y of a control relative to the form, regardless of how many containers are stacked between the form and the control.
As you may or may not know, when you check something like a controls bounds, or top/left properties, they are relative to the controls container, so if a control is in a groupbox, which is in a panel, which is on a form, then there is no property of the control itself (that I noticed anyway) to give you its x/y relative to the form.
That being said, I did already resolve this with the following code.
It just loops from the control to the form, counting up all the containers x/y along the way. I am just wondering if anyone ever came across a better way.
Code:
Dim controlToLoop As Control = Button1
Dim parentForm As Form = controlToLoop.FindForm
Dim finalLocation As New Point(0, 0)
If parentForm Is Nothing Then Return
Do
With finalLocation
.X += controlToLoop.Left
.Y += controlToLoop.Top
End With
controlToLoop = controlToLoop.Parent
Loop While controlToLoop IsNot parentForm
Re: [2008] get a controls x/y relative to form
I don't know of a direct function but it might possibly more efficient to go PointToScreen off of the immediate control and then use those coordinates to go PointToClient with the Form.
Re: [2008] get a controls x/y relative to form
What if you did a PointToScreen and then translated that back to a PointToClient as the PointToClient should resolve to the Forms orgin point instead. But perhaps using a combination of the two you can resolve it to the forms orgin with PointtoScreen if the PointToClient does resolve to the containers location orgin and not the Forms orgin location.
Re: [2008] get a controls x/y relative to form
This appears to work:
Code:
MessageBox.Show(Me.Button1.FindForm.PointToClient(Me.Button1.PointToScreen(Me.Button1.Location)).ToString)
Re: [2008] get a controls x/y relative to form
Try it against a nested control. One that is in a Panel or GroupBox.
Re: [2008] get a controls x/y relative to form
Well it does work except you need to subtract to location coords of the immediate control from the final answer as given above.
Edit: Changed word to Control
Re: [2008] get a controls x/y relative to form
I.e.
Code:
MessageBox.Show((Me.Button1.FindForm.PointToClient(Me.Button1.PointToScreen(Me.Button1.Location)) - New Size(Me.Button1.Location)).ToString)
Re: [2008] get a controls x/y relative to form
I nested a Button inside a Panel, inside a Panel, inside a GroupBox and it worked as listed in my last post.
I don't know if it's any more efficient though.
Re: [2008] get a controls x/y relative to form
Thanks for testing it. :thumb:
Re: [2008] get a controls x/y relative to form
This is a little more non-specific:
Code:
Private Function FindFormCoordinates(ByVal control As Control) As Point
Return control.FindForm.PointToClient(control.PointToScreen(control.Location) - New Size(control.Location))
End Function
If you find a problem with it, please let me know.
If you find a more efficient method, please let me know.
If you find there's a framework method, please let me know.
If you get tired of letting me know, don't let me know. :bigyello:
Re: [2008] get a controls x/y relative to form
All the suggested methods seem to work, but I am not sure if there is anything I gain by using one over mine.
I can do some performance testing, because the code is actually used with some painting code, so speed will be somewhat important if there is a decent difference between the methods.
Re: [2008] get a controls x/y relative to form
Quote:
Originally Posted by FourBlades
This is a little more non-specific:
Code:
Private Function FindFormCoordinates(ByVal control As Control) As Point
Return control.FindForm.PointToClient(control.PointToScreen(control.Location) - New Size(control.Location))
End Function
If you find a problem with it, please let me know.
If you find a more efficient method, please let me know.
If you find there's a framework method, please let me know.
If you get tired of letting me know, don't let me know. :bigyello:
Actually, You could take this, but simplify it down to this
(where C is the control to get coords of)
Code:
Return C.FindForm.PointToClient(C.Parent.PointToScreen(C.Location))
Re: [2008] get a controls x/y relative to form
I knew as soon as I did the subtraction that that implied a simplification was available...just didn't look for one since I didn't know if the whole thing was useful at all.
Thanks for the post back. :wave:
Re: [2008] get a controls x/y relative to form
well im almost done with this little project and it has some nice results so I will post the source once im done.
Re: [2008] get a controls x/y relative to form
Quote:
Originally Posted by FourBlades
This is a little more non-specific:
Code:
Private Function FindFormCoordinates(ByVal control As Control) As Point
Return control.FindForm.PointToClient(control.PointToScreen(control.Location) - New Size(control.Location))
End Function
If you find a problem with it, please let me know.
If you find a more efficient method, please let me know.
If you find there's a framework method, please let me know.
If you get tired of letting me know, don't let me know. :bigyello:
Sadly I broke it, it doesn't seem to work inside splitframes.
Anhar
Re: [2008] get a controls x/y relative to form
I haven't read this whole thread but I didn't see the "most correct" answer posted so here goes:
vb.net Code:
Me.PointToClient(Me.MyControl.PointToScreen(Point.Empty))
Of course, because this is VB 2008 you could create an extension method:
vb.net Code:
Imports System.Runtime.CompilerServices
Imports System.Windows.Forms
Module ControlExtensions
<Extension()> _
Public Function PointToForm(ByVal target As Control, ByVal p As Point) As Point
Return target.FindForm().PointToClient(target.PointToScreen(p))
End Function
End Module
and then call it as though it's a member of the control:
vb.net Code:
Dim loc As Point = Me.Button1.PointToForm(Point.Empty)
or even more specific:
vb.net Code:
Imports System.Runtime.CompilerServices
Imports System.Windows.Forms
Module ControlExtensions
<Extension()> _
Public Function GetLocationInForm(ByVal target As Control) As Point
Return target.FindForm().PointToClient(target.PointToScreen(Point.Empty))
End Function
End Module
and then call it as though it's a member of the control:
vb.net Code:
Dim loc As Point = Me.Button1.GetLocationInForm()