C# 将鼠标事件传递给父控件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/547172/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 07:41:17  来源:igfitidea点击:

Pass-through mouse events to parent control

c#winformsmouseevent

提问by GentlemanCoder

Environment: .NET Framework 2.0, VS 2008.

环境:.NET Framework 2.0,VS 2008。

I am trying to create a subclass of certain .NET controls (label, panel) that will pass through certain mouse events (MouseDown, MouseMove, MouseUp) to its parent control (or alternatively to the top-level form). I can do this by creating handlers for these events in instances of the standard controls, e.g.:

我正在尝试创建某些 .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);
    }
}

I cannot move the event handler into a subclass of the control, because the methods that raise the events in the parent control are protected and I don't have a qualifier for the parent control:

我无法将事件处理程序移动到控件的子类中,因为在父控件中引发事件的方法是受保护的,并且我没有父控件的限定符:

Cannot access protected member System.Windows.Forms.Control.OnMouseDown(System.Windows.Forms.MouseEventArgs)via a qualifier of type System.Windows.Forms.Control; the qualifier must be of type TheProject.NoCaptureLabel(or derived from it).

无法System.Windows.Forms.Control.OnMouseDown(System.Windows.Forms.MouseEventArgs)通过类型的限定符访问受保护的成员System.Windows.Forms.Control;限定符必须是类型TheProject.NoCaptureLabel(或派生自类型)。

I am looking into overriding the WndProcmethod of the control in my sub-class, but hopefully someone can give me a cleaner solution.

我正在考虑WndProc在我的子类中覆盖控件的方法,但希望有人能给我一个更清晰的解决方案。

采纳答案by akatran

Yes. After a lot of searching, I found the article "Floating Controls, tooltip-style", which uses WndProcto change the message from WM_NCHITTESTto HTTRANSPARENT, making the Controltransparent to mouse events.

是的。经过大量搜索,我找到了文章“浮动控件,工具提示样式”,它用于WndProc将消息从 更改WM_NCHITTESTHTTRANSPARENT,使Control鼠标事件透明。

To achieve that, create a control inherited from Labeland simply add the following code.

要实现这一点,请创建一个继承自的控件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);
    }
}

I have tested this in Visual Studio 2010 with .NET Framework 4 Client Profile.

我已经在带有 .NET Framework 4 Client Profile 的 Visual Studio 2010 中对此进行了测试。

回答by Autodidact

You need to write a public/protected method in your base class which will raise the event for you. Then call this method from the derived class.

您需要在基类中编写一个公共/受保护的方法,它会为您引发事件。然后从派生类调用这个方法。

OR

或者

Is this what you want?

这是你想要的吗?

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

回答by Jeff Yates

The WS_EX_TRANSPARENTextended window style actually does this (it's what in-place tooltips use). You might want to consider applying this style rather than coding lots of handlers to do it for you.

WS_EX_TRANSPARENT扩展的窗口风格其实做到这一点(这是就地工具提示使用什么)。您可能需要考虑应用这种风格,而不是编写大量处理程序来为您完成。

To do this, override the CreateParamsmethod:

为此,请覆盖该CreateParams方法:

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

For further reading:

进一步阅读: