5

This is the inverse question to C# Get a control's position on a form.

Given a Point location within a form, how can I find out which control is visible to the user at that position?

I'm currently using the HelpRequested form event to show a separate help form as shown in MSDN: MessageBox.Show Method.

In the MSDN example the events sender control is used to determine the help message, but the sender is always the form and not the control in my case.

I'd like to use the HelpEventArgs.MousePos to get the specific control within the form.

Community
  • 1
  • 1
Daniel Ballinger
  • 13,187
  • 11
  • 69
  • 96

3 Answers3

6

You can use the Control.GetChildAtPoint method on the form. You may have to do this recursively if you need to go several levels deep. Please see this answer as well.

Community
  • 1
  • 1
Bryan
  • 963
  • 4
  • 8
  • 1
    Thats a good start, thanks. GetChildAtPoint is "relative to the upper-left corner of the control's client area" while HelpEventArgs.MousePos gives screen coordinates of the mouse pointer. So I'll need to do some conversions to get usable point before I can recursively search for the specific control. – Daniel Ballinger Jan 23 '11 at 21:05
2

You can use Control.GetChildAtPoint:

var controlAtPoint = theForm.GetChildAtPoint(thePosition);
Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
1

This is at extract of the modified code using both Control.GetChildAtPoint and Control.PointToClient to recursively search for the control with a Tag defined at the point the user clicked at.

private void Form1_HelpRequested(object sender, HelpEventArgs hlpevent)
{
    // Existing example code goes here.

    // Use the sender parameter to identify the context of the Help request.
    // The parameter must be cast to the Control type to get the Tag property.
    Control senderControl = sender as Control;

    //Recursively search below the sender control for the first control with a Tag defined to use as the help message.
    Control controlWithTag = senderControl;
    do
    {
        Point clientPoint = controlWithTag.PointToClient(hlpevent.MousePos);
        controlWithTag = controlWithTag.GetChildAtPoint(clientPoint);

    } while (controlWithTag != null && string.IsNullOrEmpty(controlWithTag.Tag as string));

    // Existing example code goes here.    
}
Daniel Ballinger
  • 13,187
  • 11
  • 69
  • 96