En mis pruebas, tanto las soluciones de Fredrik MORK de Hans Kesting y di la misma respuesta. Pero:
Encontré una discrepancia interesante en la respuesta usando los métodos de Raj More y Hans Kesting, y pensé que compartiría. Gracias a ambos por su ayuda; No puedo creer que ese método no esté incorporado en el marco.
Tenga en cuenta que Raj no escribió el código y, por lo tanto, mi implementación podría ser diferente de lo que quería decir.
La diferencia que encontré fue que el método de Raj More a menudo tendría dos píxeles más (tanto en X como en Y) que el método de Hans Kesting. Todavía no he determinado por qué ocurre esto. Estoy bastante seguro de que tiene algo que ver con el hecho de que parece haber un borde de dos píxeles alrededor del contenido de un formulario de Windows (como en, dentro de los bordes más externos del formulario). En mi prueba, que ciertamente no fue exhaustiva en ningún sentido, solo me he encontrado con controles anidados. Sin embargo, no todos los controles anidados lo exhiben. Por ejemplo, tengo un TextBox dentro de un GroupBox que muestra la discrepancia, pero un botón dentro del mismo GroupBox no lo hace. No puedo explicar por qué.
Tenga en cuenta que cuando las respuestas son equivalentes, consideran que el punto (0, 0) es dentro de el borde de contenido que mencioné anteriormente. Por lo tanto, creo que consideraré que las soluciones de Hans Kesting y Fredrik Mörk son correctas, pero no creo que confíe en la solución que implementé de Raj More's.
También me pregunté exactamente qué código habría escrito Raj More, ya que dio una idea pero no proporcionó el código.No entendí completamente el método PointToScreen() hasta que leí esta publicación: http://social.msdn.microsoft.com/Forums/en-US/netfxcompact/thread/aa91d4d8-e106-48d1-8e8a-59579e14f495
Aquí está mi método para probar. Tenga en cuenta que el 'Método 1' mencionado en los comentarios es ligeramente diferente al de Hans Kesting.
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;
}
Esta es la 'POSICIÓN REAL ABSOULUTE' http://stackoverflow.com/questions/4998076/getting-the-location-of-a-control-relative-to-the-entire-screen – PUG
¿Cómo se diferencia esto de' control .PointToScreen (Point.Empty); '? – strongriley
@strongriley No tengo idea (nunca lo intenté y no tengo env env disponible en este momento), pero no puedo ver ese comportamiento mencionado en la documentación y, de ser así, no hay garantía de que funcione en futuras versiones del framework. –