【问题标题】:Detect mouse location within ContainerControl C#.NET [duplicate]在 ContainerControl C#.NET 中检测鼠标位置 [重复]
【发布时间】:2013-01-26 16:22:13
【问题描述】:

我正在测试以下代码:

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 事件,即使它的子级填充相同的矩形区域?

【问题讨论】:

  • @JohnKoerner 可能需要注意的是,强制子控件透明会完全将它们从事件链中删除 - 您将失去每个子控件拥有自己的 MouseMove 代码的能力,因为事件直接钻到父控件。下面的方法允许子控件保留处理移动事件的能力,但也可以将事件冒泡到顶部控件。

标签: c# .net mouseevent gdi+ gdi


【解决方案1】:

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 事件处理程序中执行代码。有许多其他解决方案可以将其构建到派生类中,但这里的重点是识别子控件并将其连接到单个事件的方法。

【讨论】:

  • 您好,感谢您的回答。我对 WPF 并没有过多的经验(尽管我应该是,因为 WinForms 似乎正在下降)。
猜你喜欢
  • 1970-01-01
  • 2014-10-30
  • 2018-12-25
  • 2023-03-03
  • 1970-01-01
  • 2022-01-21
  • 1970-01-01
  • 1970-01-01
  • 2015-02-12
相关资源
最近更新 更多