Thursday, March 31, 2011

c# pass through mouse events to parent control

Environment: .NET Framework 2.0, VS 2008, C#

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 toplevel form). I can do this by creating handlers for these events in instances of the standard controls, e.g.

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:

Error 1 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) C:\Documents and Settings\Me\My Documents\Visual Studio 2008\Projects\theProject\NoCaptureControls.cs 30 22 theProject

I am looking into overriding the WndProc() method of the control in my subclass but hoping someone can give me a cleaner solution. TIA

From stackoverflow
  • 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
        }
    }
    
    GentlemanCoder : I don't think so. OnMouseDown *raises* the event, it does not handle it. I need an event handler that passes the event to it's parent. And I can't do your first suggestion b/c the base class is a standard Windows control, not a class that I wrote.
  • The WS_EX_TRANSPARENT extended 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.

    To do this, override the CreateParams method:

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

    For further reading:

    GentlemanCoder : Thanks for the suggestion. I tried it and it does not work in my case. Perhaps it only works for top level windows?

0 comments:

Post a Comment