67 votes

C# Obtenir la position d'un contrôle sur un formulaire

Existe-t-il un moyen de récupérer la position d'un contrôle dans un formulaire, lorsque ce contrôle peut se trouver à l'intérieur d'autres contrôles (comme des panneaux) ?

Les propriétés Left et Top du contrôle me donnent uniquement sa position dans le contrôle parent, mais que se passe-t-il si mon contrôle se trouve dans cinq panneaux imbriqués et que j'ai besoin de sa position sur le formulaire ?

Un exemple rapide :

Le bouton btnA est situé aux coordonnées (10,10) à l'intérieur du panneau pnlB.
Le panneau pnlB est situé aux coordonnées (15,15) à l'intérieur du formulaire frmC.

Je veux l'emplacement de btnA sur frmC, qui est (25,25).

Puis-je obtenir cet emplacement ?

92voto

Fredrik Mörk Points 85694

Je combine habituellement PointToScreen et PointToClient :

Point locationOnForm = control.FindForm().PointToClient(
    control.Parent.PointToScreen(control.Location));

11voto

Raj More Points 22358

Vous pouvez utiliser les contrôles PointToScreen pour obtenir la position absolue par rapport à l'écran.

Vous pouvez faire les formulaires PointToScreen et, à l'aide de calculs élémentaires, obtenir la position du contrôle.

6voto

Hans Kesting Points 17043

Vous pourriez remonter à travers les parents, en notant leur position dans leur parent, jusqu'à ce que vous arriviez à la Forme.

Edit : Quelque chose comme (non testé) :

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;
}

5voto

Plater Points 51

Supergeek, votre fonction non récursive n'a pas produit le bon résultat, mais la mienne oui. Je crois que la tienne fait une addition de trop.

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

3voto

BoeroBoy Points 289

Curieusement, PointToClient et PointToScreen n'étaient pas idéaux pour ma situation. En particulier parce que je travaille avec des contrôles hors écran qui ne sont associés à aucun formulaire. J'ai trouvé la solution de Sahin la plus utile, mais j'ai supprimé la récursion et éliminé la terminaison de formulaire. La solution ci-dessous fonctionne pour n'importe lequel de mes contrôles, qu'il soit visible ou non, qu'il soit associé à un formulaire ou non, qu'il soit intégré ou non. Merci Sahim.

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X