我正在尝试处理特定表单上的mouseclick事件,如果鼠标光标位于一组坐标之间,则应触发该事件 - 比如说一个正方形。
我明白,如果我有一个空的表格,我可以简单地绑定到mousemove事件,然后离开。但实际上可能有多达10个不同的重叠控件,在我的测试应用程序中,mousemove事件仅在光标位于实际表单本身时触发,而不是在其通过子控件时触发。
当设计时存在未知数量的子控件时,是否有人知道如何处理此事件?
我可以使用简单的单行程吗?
答案 0 :(得分:7)
试试这个:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
AddMouseMoveHandler(this);
}
private void AddMouseMoveHandler(Control c)
{
c.MouseMove += MouseMoveHandler;
if(c.Controls.Count>0)
{
foreach (Control ct in c.Controls)
AddMouseMoveHandler(ct);
}
}
private void MouseMoveHandler(object sender, MouseEventArgs e)
{
lblXY.Text = string.Format("X: {0}, Y:{1}", e.X, e.Y);
}
}
答案 1 :(得分:7)
我知道这篇文章很老了,但在我看来,最简单的方法是实现IMessageFilter
的形式。在构造函数中(或在OnHandleCreated
中),您可以调用
Application.AddMessageFilter(this);
然后您可以在IMessageFilter.PreFilterMessage
的实现中捕获所有窗口的消息。
您可能需要为WIN32 IsChild方法使用P / Invoke
[DllImport("user32.dll")]
public static extern bool IsChild(IntPtr hWndParent, IntPtr hWnd);
以及表单的Handle
属性,以确保您处理正确的邮件。
答案 2 :(得分:0)
为什么不直接使用控件的鼠标悬停事件处理程序?
答案 3 :(得分:0)
imho这里有一些二元情况:并没有“一线”。我能看到的唯一解决方案是将没有实现事件的控件放入.NET容器中。
当任何控件获得单击时,正常的预期行为是它将成为表单的活动控件(可以始终通过this.ActivceControl访问)。
但是,特别是如果您单击的控件捕获鼠标,则必须引发事件,因为.NET未实现事件“冒泡”(如WPF所做的那样)。
处理任何密封对象的扩展行为的常用方法是编写扩展方法,我发现为Control编写扩展非常容易,但我不知道这是否会对你有所帮助案件。不幸的是,我现在不在我的国家,也没有Visual Studio可以玩。
您可以使用一种策略来确定表单上的给定Point是否属于任何Control的范围,是通过Forms Control.Collection(此处)的forall枚举表单上所有控件的区域(Bounds)。控制)。但是,如果您有重叠的控件,那么您可能会遇到多个可能包含给定点的控件的问题。
最好,比尔
答案 4 :(得分:0)
我知道我有点迟到了,但今天早些时候我使用Panel作为标题栏时遇到了麻烦。我有一个标签显示一些文本,一个图片框和一些嵌套在Panel中的按钮,但我需要捕获MouseMove事件。
我决定要做的是实现一个递归方法处理程序来执行此操作,因为我只有1级嵌套控件,当你开始接近荒谬的嵌套级别时,这可能无法很好地扩展。
我是这样做的:
protected virtual void NestedControl_Mousemove(object sender, MouseEventArgs e)
{
Control current = sender as Control;
//you will need to edit this to identify the true parent of your top-level control. As I was writing a custom UserControl, "this" was my title-bar's parent.
if (current.Parent != this)
{
// Reconstruct the args to get a correct X/Y value.
// you can ignore this if you never need to get e.X/e.Y accurately.
MouseEventArgs newArgs = new MouseEventArgs
(
e.Button,
e.Clicks,
e.X + current.Location.X,
e.Y + current.Location.Y,
e.Delta
);
NestedControl_Mousemove(current.Parent, newArgs);
}
else
{
// My "true" MouseMove handler, called at last.
TitlebarMouseMove(current, e);
}
}
//helper method to basically just ensure all the child controls subscribe to the NestedControl_MouseMove event.
protected virtual void AddNestedMouseHandler(Control root, MouseEventHandler nestedHandler)
{
root.MouseMove += new MouseEventHandler(nestedHandler);
if (root.Controls.Count > 0)
foreach (Control c in root.Controls)
AddNestedMouseHandler(c, nestedHandler);
}
然后设置起来相对简单:
定义“真正的”处理程序:
protected virtual void TitlebarMouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
this.Text = string.Format("({0}, {1})", e.X, e.Y);
}
}
然后设置控件事件订阅者:
//pnlDisplay is my title bar panel.
AddNestedMouseHandler(pnlDisplay, NestedControl_Mousemove);
使用相对简单,我可以保证它的工作原理:)