在UserControl中捕获包含控件的鼠标事件

时间:2010-07-16 20:26:36

标签: .net winforms user-controls

我的UserControl包含另一个UserControl。我希望包含控件能够处理在包含的控件区域内发生的任何鼠标事件。最简单的方法是什么?

可以更改所包含控件的代码,但这只是最后的手段。包含的控件有一个由非托管库控制的窗口。

FWIW,我尝试为包含控件的鼠标事件添加处理程序,但这些处理程序永远不会被调用。我怀疑所包含的控件正在消耗鼠标事件。

我考虑在包含的控件之上添加某种透明窗口,以捕获事件,但我仍然是Windows Forms的新手,我想知道是否有更好的方法。

3 个答案:

答案 0 :(得分:1)

如果内部控件未密封,您可能希望将其子类化并覆盖与鼠标相关的方法:

protected override void OnMouseClick(MouseEventArgs e) {
    //if you still want the control to process events, uncomment this:
    //base.OnMouseclick(e)

    //do whatever
}

答案 1 :(得分:1)

嗯,这在技术上是可行的。您必须自己重定向鼠标消息,这需要一点P / Invoke。将此代码粘贴到内部UserControl类中:

    protected override void WndProc(ref Message m) {
        // Re-post mouse messages to the parent window
        if (m.Msg >= 0x200 && m.Msg <= 0x209 && !this.DesignMode && this.Parent != null) {
            Point pos = new Point(m.LParam.ToInt32() & 0xffff, m.LParam.ToInt32() >> 16);
            // Fix mouse position to be relative from parent's client rectangle
            pos = this.PointToScreen(pos);
            pos = this.Parent.PointToClient(pos);
            IntPtr lp = (IntPtr)(pos.X + pos.Y << 16);
            PostMessage(this.Parent.Handle, m.Msg, m.WParam, lp);
            return;
        }
        base.WndProc(ref m);
    }

    [System.Runtime.InteropServices.DllImport("user32.dll")]
    private static extern IntPtr PostMessage(IntPtr hWnd, int msg, IntPtr wp, IntPtr lp);

最好避免顺便说一句。父控件应该只是订阅内部控件的鼠标事件。

答案 2 :(得分:0)

这就是我的所作所为:

首先,我定义了一个TransparentControl类,它只是一个透明的控件,不会绘制任何东西。 (此代码归功于http://www.bobpowell.net/transcontrols.htm。)

public class TransparentControl : Control
{
    protected override CreateParams CreateParams
    {
        get
        {
            CreateParams cp = base.CreateParams;
            cp.ExStyle |= 0x00000020; //WS_EX_TRANSPARENT
            return cp;
        }
    }

    protected override void OnPaint(PaintEventArgs pe)
    {
        // Do nothing
    }

    protected override void OnPaintBackground(PaintEventArgs pevent)
    {
        // Do nothing
    }
}

然后,我在我的用户控件中放置了一个TransparentControl在所包含的用户控件之上,并为其鼠标事件添加了处理程序。