2009-02-13 35 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; 
    } 
} 

对于进一步阅读: