我在整个表单中找到how to capture mouse clicks,但此方法对MouseEnter
和MouseLeave
的转换效果不佳。我的表单布局由许多Panels
和TableLayoutPanels
组成,因此我无法监控事件的全方位控制,显然按钮的MouseLeave
事件并不意味着光标离开了整个表格。有没有人想出一个解决这个问题的好方法?
答案 0 :(得分:3)
开始的地方是检查ClientRectangle是否包含当前鼠标位置。因此,例如,在MouseMove处理程序上,您可以:
if (ClientRectangle.Contains(e.Location))
{
bool mouseIsOverThisControl = true;
}
答案 1 :(得分:0)
使用合理的Interval(可能是50ms)向表单添加一个计时器。在Tick事件处理程序中使用此代码以查看鼠标是否在表单上:
// Check if mouse is currently over the form
bool temp_mof = ClientRectangle.Contains(
Form.MousePosition.X - Location.X,
Form.MousePosition.Y - Location.Y);
编辑:这是一个更完整的解决方案,用于检测鼠标是否在表单上并且单击了按钮。 timer1Tick()
是表单上Timer的Tick事件处理程序。没有必要为表单上的其他控件添加其他事件处理程序。这将使您的表单成为“一个巨大的按钮”:)
bool m_mouse_over_form = false;
// Assume the left button is down at onset
bool m_left_button_down = true;
void timer1Tick (object sender, EventArgs e)
{
// Check if mouse is currently over the form
bool temp_mof = ClientRectangle.Contains(
Form.MousePosition.X - Location.X,
Form.MousePosition.Y - Location.Y);
// were we already over the form before this tick?
if (temp_mof && m_mouse_over_form)
{
// we need to detect the mouse down and up to avoid
// repeated calls if the mouse button is held down for more
// than our Tick interval
// was the mouse button up prior to now?
if (!m_left_button_down)
{
// is the button down now?
m_left_button_down = (MouseButtons == MouseButtons.Left);
if (m_left_button_down)
{
// the button was down and has now been released
LeftButtonClickHandler();
}
else
{
// do nothing, the button has not been release yet
}
}
else
{
// update the button state
m_left_button_down = (MouseButtons == MouseButtons.Left);
}
}
else if (temp_mof)
{
// the mouse just entered the form
m_mouse_over_form = true;
// set the initial state of the left button
m_left_button_down = MouseButtons == MouseButtons.Left);
}
else
{
// the mouse is not currently over the form
m_mouse_over_form = false;
m_left_button_down = true;
}
}
答案 2 :(得分:0)
正如有人指出here,可以使用SetWindowsHookEx()或将MouseMove事件挂接到表单中的所有控件上。后者对我很好。唯一的缺点是如果在运行时添加/删除控件,则可能需要另一种解决方案。
using System;
using System.Drawing;
using System.Windows.Forms;
namespace WindowsForms_MouseEvents
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
MouseMove += OnMouseMove;
MouseLeave += OnMouseLeave;
HookMouseMove(this.Controls);
}
private void HookMouseMove(Control.ControlCollection ctls)
{
foreach (Control ctl in ctls)
{
ctl.MouseMove += OnMouseMove;
HookMouseMove(ctl.Controls);
}
}
private void OnMouseMove(object sender, MouseEventArgs e)
{
BackColor = Color.Plum;
Control ctl = sender as Control;
if (ctl != null)
{
// Map mouse coordinate to form
Point loc = this.PointToClient(ctl.PointToScreen(e.Location));
Console.WriteLine("Mouse at {0},{1}", loc.X, loc.Y);
}
}
private void OnMouseLeave(object sender, EventArgs e)
{
BackColor = Color.Gray;
}
}
}
答案 3 :(得分:0)
我找到了一些接近我想要的答案,但我做了不同的事情。我想检测鼠标是否离开了表单区域(包括标题栏),这对我有用:
在表单构造函数中,我添加了一个计时器:
Inherited
然后在tick方法中,我执行以下操作:
time.Interval = 250;
time.Tick += time_Tick;
time.Start();
答案 4 :(得分:0)
在表单和表单控件上执行MouseEnter和MouseLeave事件;使用布尔值来确定鼠标是输入还是离开。
一个例子是
private static bool mouseEnteredForm
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
mouseEnteredForm = true;
Form.MouseLeave += Form1_MouseLeave;
CheckMouseLocation();
}
private void Form1_MouseLeave(object sender, MouseEventArgs e)
{
mouseEnteredForm = false
CheckMouseLocation();
}
private static void CheckMouseLocation()
{
if(!mouseOverForm)
{
MessageBox.Show("Mouse Not Over Form!);
}
else if(mouseOverForm) //else if is optional. You could also use else in this case. I used else if for the sake of the example.
{
MessageBox.Show("Mouse Is Over Form");
}
}
如果表单上有很多对象,这可能会很繁琐