2009-02-13 17 views
29

環境:.NET框架2.0,VS 2008直通鼠標事件於母公司控制

我試圖創造條件,通過一定的鼠標事件,某些.NET控件(標籤,面板)的一個子類( MouseDown,MouseMove,MouseUp)到其父控制(或頂級表單)。我可以通過在標準控件的實例,例如創建這些事件的處理程序做到這一點:

public class TheForm : Form 
{ 
    private Label theLabel; 

    private void InitializeComponent() 
    { 
     theLabel = new Label(); 
     theLabel.MouseDown += new MouseEventHandler(theLabel_MouseDown); 
    } 

    private void theLabel_MouseDown(object sender, MouseEventArgs e) 
    { 
     int xTrans = e.X + this.Location.X; 
     int yTrans = e.Y + this.Location.Y; 
     MouseEventArgs eTrans = new MouseEventArgs(e.Button, e.Clicks, xTrans, yTrans, e.Delta); 
     this.OnMouseDown(eTrans); 
    } 
} 

我可以在事件處理程序不能移動到控制的子類,因爲這提高了事件父控件的方法受到保護,我沒有父控件限定符:

無法通過System.Windows.Forms.Control類型的限定符訪問保護成員System.Windows.Forms.Control.OnMouseDown(System.Windows.Forms.MouseEventArgs);限定符必須是TheProject.NoCaptureLabel(或從中派生)。

我期待到重載控件的WndProc方法在我的子類,但希望有人可以給我一個清晰的解決方案。

+0

這是該代碼的正確錯誤消息嗎?一個是MouseUp,另一個是MouseDown。 – 2009-11-19 16:35:12

+0

我也不太清楚你是什麼意思的「通過」。 – 2009-11-19 16:36:35

+0

錯誤消息不正確,應該是MouseDown。 我的意思是「通過」是,當控件上發生某些事件時,我通過編程方式在控件的父級上引發它們。 – GentlemanCoder 2009-11-23 14:11:47

回答

55

是。經過大量搜索之後,我發現文章"Floating Controls, tooltip-style",它使用WndProc將消息從WM_NCHITTEST更改爲HTTRANSPARENT,使Control對鼠標事件透明。

要實現這一點,請創建一個從Label繼承的控件,並簡單地添加以下代碼。

protected override void WndProc(ref Message m) 
{ 
    const int WM_NCHITTEST = 0x0084; 
    const int HTTRANSPARENT = (-1); 

    if (m.Msg == WM_NCHITTEST) 
    { 
     m.Result = (IntPtr)HTTRANSPARENT; 
    } 
    else 
    { 
     base.WndProc(ref m); 
    } 
} 

我已經在Visual Studio 2010中用.NET Framework 4 Client Profile進行了測試。

3

您需要在您的基類中編寫一個公共/受保護方法,以便爲您提供事件。然後從派生類中調用此方法。

這是你想要的嗎?

public class MyLabel : Label 
{ 
    protected override void OnMouseDown(MouseEventArgs e) 
    { 
     base.OnMouseDown(e); 
     //Do derived class stuff here 
    } 
} 
+0

我不這麼認爲。 OnMouseDown *引發事件,它不處理它。我需要一個將事件傳遞給它的父級的事件處理程序。我不能做你的第一個建議b/c基類是一個標準的Windows控件,而不是我寫的類。 – GentlemanCoder 2009-02-13 19:14:42

3

WS_EX_TRANSPARENT擴展窗口樣式實際上是這樣做的(它是就地使用的工具提示)。你可能想考慮應用這種風格,而不是編寫大量的處理程序來爲你做。

要做到這一點,覆蓋CreateParams方法:

protected override CreateParams CreateParams 
{ 
    get 
    { 
    CreateParams cp=base.CreateParams; 
    cp.ExStyle|=0x00000020; //WS_EX_TRANSPARENT 
    return cp; 
    } 
} 

對於進一步閱讀: