2010-07-16 99 views
0

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

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

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

我曾考虑过在包含的控件的顶部添加某种透明窗口来捕捉事件,但对于Windows窗体我仍然很新,我想知道是否有更好的方法。

回答

1

如果内部控制不密封,你可能要继承它,并覆盖鼠标相关的方法:

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

    //do whatever 
} 

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); 

这是最好避免顺便说一句。父控件可能只需订阅内部控件的鼠标事件。

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,并加入处理程序为它的鼠标事件。