How to get control under mouse cursor? [duplicate]

2019-01-06 19:39发布

问题:

This question already has an answer here:

  • Is there a quick way to get the control that's under the mouse? 2 answers

I have form with few buttons and I want to know what button is under cursor now.

P.S. Maybe it's duplicate, but I can't find answer to this question.

回答1:

Have a look at GetChildAtPoint. You will have to do some extra work if the controls are contained in a container, see Control.PointToClient.



回答2:

Maybe GetChildAtPoint and PointToClient is the first idea for most people. I also used it first. But, GetChildAtPoint doesn't work properly with invisible or overlapped controls. Here's my well-working code and it manages those situations.

using System.Drawing;
using System.Windows.Forms;

public static Control FindControlAtPoint(Control container, Point pos)
{
    Control child;
    foreach (Control c in container.Controls)
    {
        if (c.Visible && c.Bounds.Contains(pos))
        {
            child = FindControlAtPoint(c, new Point(pos.X - c.Left, pos.Y - c.Top));
            if (child == null) return c;
            else return child;
        }
    }
    return null;
}

public static Control FindControlAtCursor(Form form)
{
    Point pos = Cursor.Position;
    if (form.Bounds.Contains(pos))
        return FindControlAtPoint(form, form.PointToClient(pos));
    return null;
}

This will give you the control right under the cursor.



回答3:

// This getYoungestChildUnderMouse(Control) method will recursively navigate a       
// control tree and return the deepest non-container control found under the cursor.
// It will return null if there is no control under the mouse (the mouse is off the
// form, or in an empty area of the form).
// For example, this statement would output the name of the control under the mouse
// pointer (assuming it is in some method of Windows.Form class):
// 
// Console.Writeline(ControlNavigatorHelper.getYoungestChildUnderMouseControl(this).Name);


    public class ControlNavigationHelper
    {
        public static Control getYoungestChildUnderMouse(Control topControl)
        {
            return ControlNavigationHelper.getYoungestChildAtDesktopPoint(topControl, System.Windows.Forms.Cursor.Position);
        }

        private static Control getYoungestChildAtDesktopPoint(Control topControl, System.Drawing.Point desktopPoint)
        {
            Control foundControl = topControl.GetChildAtPoint(topControl.PointToClient(desktopPoint));
            if ((foundControl != null) && (foundControl.HasChildren))
                return getYoungestChildAtDesktopPoint(foundControl, desktopPoint);
            else
                return foundControl;
        }
    }


回答4:

You could do it a number of ways:

  1. Listen to the MouseEnter event of your form's controls. The "sender" parameter will tell you what control raised the event.

  2. Obtain the cursor position using System.Windows.Forms.Cursor.Location and map it to your form's coordinates using Form.PointToClient(). You can then pass the point to Form.GetChildAtPoint() to find the control under that point.

Andrew



回答5:

What about defining an on-Mouse-over event in each button which assigns the sender button to a public variable of a button type