问题
Environment: .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.:
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 typeSystem.Windows.Forms.Control; the qualifier must be of typeTheProject.NoCaptureLabel(or derived from it).
I am looking into overriding the WndProc method of the control in my sub-class, but hopefully someone can give me a cleaner solution.
回答1:
Yes. After a lot of searching, I found the article "Floating Controls, tooltip-style", which uses WndProc to change the message from WM_NCHITTEST to HTTRANSPARENT, making the Control transparent to mouse events.
To achieve that, create a control inherited from Label and simply add the following code.
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.
回答2:
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
}
}
回答3:
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:
- http://support.microsoft.com/kb/92526
- http://msdn.microsoft.com/en-us/library/ms632680.aspx
来源:https://stackoverflow.com/questions/547172/pass-through-mouse-events-to-parent-control