.NET:如何检查鼠标是否在控件中?

时间:2011-11-16 22:18:36

标签: .net winforms

我想知道鼠标是否在.NET中的特定控件中

private void panel1_MouseLeave(object sender, EventArgs e)
{
   if (MouseIsInControl((Control)sender)
      return; //the mouse didn't leave, don't fire a MouseLeave event

   ...
}

public Boolean MouseIsInControl(Control control)
{
    //return (control.Bounds.Contains(MousePosition));
    return control.Bounds.Contains(control.PointToClient(MousePosition))
}

但我需要有人调整四种不同的坐标系以使其有效.

相关问题

3 个答案:

答案 0 :(得分:4)

Hans Passant Answer可以根据您的需要进行调整:

private bool mEntered;
private Timer timer1;

public Form1() {
  InitializeComponent();

  timer1 = new Timer();
  timer1.Interval = 200;
  timer1.Tick += timer1_Tick;
  timer1.Enabled = false;
}

private void panel1_MouseEnter(object sender, EventArgs e) {
  timer1.Enabled = true;
}

private void timer1_Tick(object sender, EventArgs e) {
  bool entered = panel1.ClientRectangle.Contains(panel1.PointToClient(Cursor.Position));
  if (entered != mEntered) {
    mEntered = entered;
    if (!entered) {
      timer1.Enabled = false;
      // OK, Do something, the mouse left the parent container
    }
  }
}

答案 1 :(得分:2)

不需要挂钩或子类。

private bool MouseIsOverControl(Button btn)
{
    if (btn.ClientRectangle.Contains(btn.PointToClient(Cursor.Position)))
    {
        return true;
    }
    return false;
}

如果鼠标位于包含控件的表单之外,则此方法也有效。它使用按钮对象,但您可以使用任何UI类

您可以像这样轻松地测试方法:

private void button1_Click(object sender, EventArgs e)
{

    //sleep to allow you time to move the mouse off the button

    System.Threading.Thread.Sleep(900); 

    //try moving mouse around or keeping it over the button for different results

     if (MouseIsOverControl(button1)) {
        MessageBox.Show("Mouse is over the button.");
    } else {
        MessageBox.Show("Mouse is NOT over the button.");
    }
}

答案 2 :(得分:0)

我也使用System.Windows.Forms.Timer来解决这个问题,但我不再使用进入/离开鼠标事件了。他们给我带来了太多的悲伤。相反,我在组件上使用MouseMove事件,我需要知道鼠标已经结束。我在这个类中有2个成员变量。

bool Hovering = false;
System.Drawing.Point LastKnownMousePoint = new System.Drawing.Point();

在我的情况下,我想切换标签周围的边框。我知道鼠标是否在我关心的标签控件之上,如下所示:

    private void label1_MouseMove(object sender, MouseEventArgs e)
    {
        // Mouse Position relative to the form... not the control
        LastKnownMousePoint = Cursor.Position; 

        label1.BorderStyle = BorderStyle.Fixed3D;
        timer1.Stop();
        timer1.Interval = 50; // Very fast (Overkill?  :) )
        timer1.Start();
    }

    private void timer1_Tick(object sender, EventArgs e)
    {
        System.Drawing.Point point = Cursor.Position;
        if (LastKnownMousePoint.Equals(point))
        {
            // If the mouse is somewhere on the label, I'll call that Hovering.  
            // Though not technically the MS definition, it works for me.
            Hovering = true;
        }
        else if (Hovering == false)
        {
            label1.BorderStyle = BorderStyle.None;
            timer1.Stop();
        }
        else
        {
            Hovering = false;
            // Next time the timer ticks, I'll stop the timer and
            // Toggle the border.
        }
    }

这是有效的,因为我只在鼠标悬停在控件上时更新LastKnownMousePoint(在本例中为标签)。因此,如果鼠标移动到控件之外,我不会更新LastKnownMousePoint,并且我知道现在是时候切换边框样式了。