将鼠标事件传递给父控件
环境:.NET Framework 2.0,VS 2008。
我想创build一些.NET控件(标签,面板)的子类,它将通过某些鼠标事件( MouseDown
, MouseMove
, MouseUp
)到其父控件(或顶层窗体)。 我可以通过在标准控件的实例中为这些事件创build处理程序,例如:
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 = eX + this.Location.X; int yTrans = eY + this.Location.Y; MouseEventArgs eTrans = new MouseEventArgs(e.Button, e.Clicks, xTrans, yTrans, e.Delta); this.OnMouseDown(eTrans); } }
我不能将事件处理程序移动到控件的子类中,因为引发父控件中事件的方法受到保护,而且我没有父控件的限定符:
无法通过
System.Windows.Forms.Control
types的限定符访问受保护成员System.Windows.Forms.Control.OnMouseDown(System.Windows.Forms.MouseEventArgs)
; 限定符必须是typesTheProject.NoCaptureLabel
(或从它派生)。
我正在考虑重写我的子类中的控件的WndProc
方法,但希望有人能给我一个更干净的解决scheme。
是。 经过大量的search之后,我发现文章“浮动控件,工具提示样式” ,它使用WndProc
将消息从WM_NCHITTEST
更改为HTTRANSPARENT
,使Control
对鼠标事件透明。
为此,创build一个从Label
inheritance的控件,并简单地添加下面的代码。
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进行了testing。
你需要在你的基类中写一个公共/受保护的方法,以便为你提供事件。 然后从派生类中调用此方法。
要么
这是你想要的吗?
public class MyLabel : Label { protected override void OnMouseDown(MouseEventArgs e) { base.OnMouseDown(e); //Do derived class stuff here } }
WS_EX_TRANSPARENT
扩展窗口样式实际上是这样做的(这是就地工具提示使用的)。 你可能要考虑应用这种风格,而不是编写大量的处理程序来为你做。
为此,请重写CreateParams
方法:
protected override CreateParams CreateParams { get { CreateParams cp=base.CreateParams; cp.ExStyle|=0x00000020; //WS_EX_TRANSPARENT return cp; } }
进一步阅读: