检测ContainerControl C#.NET中的鼠标位置

时间:2013-02-11 14:38:39

标签: c# .net mouseevent gdi+ gdi

我正在测试以下代码:

protected override void OnMouseMove(MouseEventArgs e)
{
    base.OnMouseMove(e);
    Rectangle leftRect = new Rectangle(0, 0, 32, this.Height);
    if (leftRect.Contains(e.Location))
    {
        MessageBox.Show("Hello World");
    }
}

这个想法是当鼠标进入容器控件左侧32像素宽的区域时,会出现一条消息(好的,在R / L中它会做其他事情,但现在这只是纯粹的测试)。

问题是,当子控件填充矩形区域时,ContainerControl不会收到MouseMove事件,因为它正由子控件处理。

所以我的问题是,如何让我的ContainerControl接收MouseMove事件,即使它的子节点填充相同的矩形区域?

1 个答案:

答案 0 :(得分:2)

WPF在这方面要好得多。我经常使用这样的函数:

public static List<Control> GetAllControlsRecurs(List<Control> list, 
                                                 Control parent)
{
    if (parent == null)
        return list;
    else
    {
        list.Add(parent);
    }
    foreach (Control child in parent.Controls)
    {
        GetAllControlsRecurs(list, child);
    }
    return list;
}

这将返回给定父控件中所有子控件及其子控件等的列表。然后你可以做类似的事情:

private void Form1_Load(object sender, EventArgs e)
{
    List<Control> ctlList = new List<Control>();
    GetAllControlsRecurs(ctlList, this);
    foreach (Control ctl in ctlList) ctl.MouseMove += Form1_MouseMove;
}

您必须使用ControlAdded处理动态添加(和删除)控件,但这至少应该为您提供一个开始。请注意,这不会在重写OnMouseMove方法中执行代码,而是在表单的MouseMove事件处理程序中执行。有许多其他解决方案可以将其构建为派生类,但重要的一点是识别并将子控件连接到单个事件的方法。