2010-07-16 106 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,並加入處理程序爲它的鼠標事件。