By Erlend D.

2009-09-25 15:31:51 8 Comments

Is there any way to retrieve a control's position in a form, when the control may be inside other controls (like Panels)?

The control's Left and Top properties gives me only it's position within it's parent control, but what if my control is inside five nested panels, and I need it's position on the form?

Quick example:

The button btnA is located on coordinates (10,10) inside the panel pnlB.
The panel pnlB is located on coordinates (15,15) inside the form frmC.

I want btnA's location on frmC, which is (25,25).

Can I get this location?


@shiroxx 2012-08-24 19:44:20

This is what i've done works like a charm

            private static int _x=0, _y=0;
        private static Point _point;
        public static Point LocationInForm(Control c)
            if (c.Parent == null) 
                _x += c.Location.X;
                _y += c.Location.Y;
                _point = new Point(_x, _y);
                _x = 0; _y = 0;
                return _point;
            else if ((c.Parent is System.Windows.Forms.Form))
                _point = new Point(_x, _y);
                _x = 0; _y = 0;
                return _point;
                _x += c.Location.X;
                _y += c.Location.Y;
            return new Point(1,1);

@noisyass2 2012-04-18 01:13:02

I usually do it like this.. Works every time..

var loc = ctrl.PointToScreen(Point.Empty);

@skamlet 2016-09-30 15:15:16

This should be the accepted answer!

@sahin 2010-10-15 16:55:01

private Point FindLocation(Control ctrl)
    if (ctrl.Parent is Form)
        return ctrl.Location;
        Point p = FindLocation(ctrl.Parent);
        p.X += ctrl.Location.X;
        p.Y += ctrl.Location.Y;
        return p;

@Plater 2011-05-20 14:33:28

Supergeek, your non recursive function did not producte the correct result, but mine does. I believe yours does one too many additions.

private Point LocationOnClient(Control c)
   Point retval = new Point(0, 0);
   for (; c.Parent != null; c = c.Parent)
   { retval.Offset(c.Location); }
   return retval;

@Raj More 2009-09-25 15:39:21

You can use the controls PointToScreen method to get the absolute position with respect to the screen.

You can do the Forms PointToScreen method, and with basic math, get the control's position.

@Erlend D. 2009-09-25 15:41:20

Yes, thank you. Perfect!

@MusiGenesis 2009-09-25 15:47:19

That's not going to work exactly right, unless you take into account the height of the titlebar and the width of the form's border.

@Tim 2009-10-13 20:33:30

How does this help for getting the control's absolute position? You have to pass in a Point object to PointToScreen(), which doesn't make sense in this case.

@Umar T. 2017-10-30 08:22:43

@Tim, you have to pass System.Drawing.Point.Empty in this case: var absolutePosition = control.PointToScreen(System.Drawing.Point.Empty);

@BoeroBoy 2011-02-18 15:59:50

Oddly enough, PointToClient and PointToScreen weren't ideal for my situation. Particularly because I'm working with offscreen controls that aren't associated with any form. I found sahin's solution the most helpful, but took out recursion and eliminated the Form termination. The solution below works for any of my controls visible or not, Form-contained or not, IContainered or not. Thanks Sahim.

private static Point FindLocation(Control ctrl)
    Point p;
    for (p = ctrl.Location; ctrl.Parent != null; ctrl = ctrl.Parent)
    return p;

@Tyler Collier 2010-02-24 18:35:56

In my testing, both Hans Kesting's and Fredrik Mörk's solutions gave the same answer. But:

I found an interesting discrepancy in the answer using the methods of Raj More and Hans Kesting, and thought I'd share. Thanks to both though for their help; I can't believe such a method is not built into the framework.

Please note that Raj didn't write code and therefore my implementation could be different than he meant.

The difference I found was that the method from Raj More would often be two pixels greater (in both X and Y) than the method from Hans Kesting. I have not yet determined why this occurs. I'm pretty sure it has something to do with the fact that there seems to be a two-pixel border around the contents of a Windows form (as in, inside the form's outermost borders). In my testing, which was certainly not exhaustive to any extent, I've only come across it on controls that were nested. However, not all nested controls exhibit it. For example, I have a TextBox inside a GroupBox which exhibits the discrepancy, but a Button inside the same GroupBox does not. I cannot explain why.

Note that when the answers are equivalent, they consider the point (0, 0) to be inside the content border I mentioned above. Therefore I believe I'll consider the solutions from Hans Kesting and Fredrik Mörk to be correct but don't think I'll trust the solution I've implemented of Raj More's.

I also wondered exactly what code Raj More would have written, since he gave an idea but didn't provide code. I didn't fully understand the PointToScreen() method until I read this post:

Here's my method for testing. Note that 'Method 1' mentioned in the comments is slightly different than Hans Kesting's.

private Point GetLocationRelativeToForm(Control c)
  // Method 1: walk up the control tree
  Point controlLocationRelativeToForm1 = new Point();
  Control currentControl = c;
  while (currentControl.Parent != null)
    controlLocationRelativeToForm1.Offset(currentControl.Left, currentControl.Top);
    currentControl = currentControl.Parent;

  // Method 2: determine absolute position on screen of control and form, and calculate difference
  Point controlScreenPoint = c.PointToScreen(Point.Empty);
  Point formScreenPoint = PointToScreen(Point.Empty);
  Point controlLocationRelativeToForm2 = controlScreenPoint - new Size(formScreenPoint);

  // Method 3: combine PointToScreen() and PointToClient()
  Point locationOnForm = c.FindForm().PointToClient(c.Parent.PointToScreen(c.Location));

  // Theoretically they should be the same
  Debug.Assert(controlLocationRelativeToForm1 == controlLocationRelativeToForm2);
  Debug.Assert(locationOnForm == controlLocationRelativeToForm1);
  Debug.Assert(locationOnForm == controlLocationRelativeToForm2);

  return controlLocationRelativeToForm1;

@Fredrik Mörk 2009-09-25 15:47:36

I usually combine PointToScreen and PointToClient:

Point locationOnForm = control.FindForm().PointToClient(

@PUG 2012-03-16 19:54:07


@strongriley 2012-07-03 14:29:12

How does this differ from control.PointToScreen(Point.Empty);?

@Fredrik Mörk 2012-07-03 18:20:22

@strongriley No idea (never tried it and no dev env available right now), but I can't see that behavior mentioned in the documentation, and if so there is no guarantee that it will function in future framework releases.

@nawfal 2012-09-01 10:43:59

@strongriley control.PointToScreen(Point.Empty) gives location with respect to screen, while the answer gives the location with repsect to top level form.

@kokbira 2012-11-19 19:43:08

hey, you helped me a lot with that :) it centers designed popups on center of program's display instead of on the center of all screens!

@Hans Kesting 2009-09-25 15:37:07

You could walk up through the parents, noting their position within their parent, until you arrive at the Form.

Edit: Something like (untested):

public Point GetPositionInForm(Control ctrl)
   Point p = ctrl.Location;
   Control parent = ctrl.Parent;
   while (! (parent is Form))
      p.Offset(parent.Location.X, parent.Location.Y);
      parent = parent.Parent;
   return p;

@armannvg 2009-09-25 15:38:31

arrggg... beat me to it :)

@Erlend D. 2009-09-25 15:39:18

Yea, I thought of that, but it seemed like a impractical way to do it, so I was hoping there was another way. If no one has any other suggestion, that's what I will do.

@MusiGenesis 2009-09-25 15:48:19

This is the way to do it, with a simple recursive function.

@mr.baby123 2013-12-15 14:06:56

what about if the control is inside a scroll ? i think it wont work...

Related Questions

Sponsored Content

61 Answered Questions

[SOLVED] What is the difference between String and string in C#?

27 Answered Questions

[SOLVED] How do I enumerate an enum in C#?

63 Answered Questions

[SOLVED] How do I calculate someone's age in C#?

  • 2008-07-31 23:40:59
  • Jeff Atwood
  • 536211 View
  • 1742 Score
  • 63 Answer
  • Tags:   c# .net datetime

9 Answered Questions

[SOLVED] What are the correct version numbers for C#?

10 Answered Questions

[SOLVED] Calling the base constructor in C#

296 Answered Questions

[SOLVED] Hidden Features of C#?

  • 2008-08-12 16:32:24
  • Serhat Ozgel
  • 658545 View
  • 1476 Score
  • 296 Answer
  • Tags:   c# hidden-features

26 Answered Questions

[SOLVED] Get int value from enum in C#

  • 2009-06-03 06:46:39
  • jim
  • 1291003 View
  • 1578 Score
  • 26 Answer
  • Tags:   c# enums casting int

24 Answered Questions

[SOLVED] Cast int to enum in C#

  • 2008-08-27 03:58:21
  • lomaxx
  • 1171851 View
  • 2845 Score
  • 24 Answer
  • Tags:   c# enums casting

23 Answered Questions

[SOLVED] How do you give a C# Auto-Property a default value?

38 Answered Questions

Sponsored Content