如何在 c# 中单击用户控件时触发窗体单击事件

本文关键字:单击 事件 窗体 控件 用户 | 更新日期: 2023-09-27 18:35:13

我需要检测来自Windows表单应用程序的所有鼠标单击,该应用程序中有许多用户控件。我可以捕获每个控件单击事件并将其传递给主窗体,但这并不可行,因为窗体有许多自定义用户控件(超过一百个),其中一些已经在使用此事件。我尝试添加单击、鼠标单击、鼠标上下事件,但如果单击用户控件而不是窗体的空白部分,则无法触发它们。我在网上搜索了可能的解决方案,但没有一个令人满意。

有没有一种实用的方法可以使表单单击事件触发,即使单击用户控件?我也提出了任何建议,可以在不使用表单单击事件的情况下记录用户的鼠标点击。

如何在 c# 中单击用户控件时触发窗体单击事件

    [System.Security.Permissions.PermissionSet(System.Security.Permissions.SecurityAction.Demand, Name = "FullTrust")]
    protected override void WndProc(ref Message m)
    {
        // 0x210 is WM_PARENTNOTIFY
        // 513 is WM_LBUTTONCLICK
        if (m.Msg == 0x210 && m.WParam.ToInt32() == 513)
        {
            // get the clicked position
            var x = (int)(m.LParam.ToInt32() & 0xFFFF);
            var y = (int)(m.LParam.ToInt32() >> 16);
            // get the clicked control
            var childControl = this.GetChildAtPoint(new Point(x, y));
            // call onClick (which fires Click event)
            OnClick(EventArgs.Empty);
            // do something else...
        }
        base.WndProc(ref m);
    }

这个问题现在已经很老了,但是有一些解决方案不涉及覆盖表单的WndProc。

例如,可以使用如下所示的内容将单击事件递归添加到控件层次结构中的所有控件:

private void SetupNestedClickEvents(Control control, EventHandler handler)
{
    control.Click += handler;
    foreach (Control ctl in control.Controls)
        SetupNestedClickEvents(ctl, handler);
}

您只需这样称呼它(ctl是您要应用它FormUserControlControl):

SetupNestedClickEvents(ctl, (sender, e) => { // Your code here });

例如:

SetupNestedClickEvents(this, (sender, e) => { Close(); });

在当前Form上运行,将设置层次结构中窗体下任意位置的任何控件,以便在单击时关闭窗体。