Pass-through eventi del mouse a controllo padre
-
23-08-2019 - |
Domanda
Ambiente: .NET Framework 2.0, VS 2008
. Sto cercando di creare una sottoclasse di alcuni controlli NET (etichetta, panel) che passeranno attraverso certi eventi del mouse (MouseDown
, MouseMove
, MouseUp
) al suo controllo padre (o in alternativa alla forma di primo livello). Posso fare questo attraverso la creazione di gestori di questi eventi nelle istanze dei controlli standard, per esempio:.
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);
}
}
Non riesco a muovere il gestore di eventi in una sottoclasse del controllo, perché i metodi che sollevano gli eventi nel controllo padre sono protetti e non ho un qualificatore per il controllo padre:
Impossibile accedere protetto
System.Windows.Forms.Control.OnMouseDown(System.Windows.Forms.MouseEventArgs)
membro attraverso un qualificatore di tipoSystem.Windows.Forms.Control
; la qualificazione deve essere di tipoTheProject.NoCaptureLabel
(o derivato da esso).
Sto cercando di override del metodo WndProc
del controllo nel mio sottoclasse, ma spero che qualcuno mi possa dare una soluzione più pulita.
Soluzione
Sì. Dopo un sacco di ricerca, ho trovato l'articolo "Controlli galleggianti, tooltip-style" , che utilizza WndProc
per cambiare il messaggio dal WM_NCHITTEST
a HTTRANSPARENT
, rendendo il Control
trasparente agli eventi del mouse.
A tal fine, creare un controllo ereditato da Label
e semplicemente aggiungere il seguente codice.
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);
}
}
Ho testato questo in Visual Studio 2010 con .NET Framework 4 Client Profile.
Altri suggerimenti
Hai bisogno di scrivere un metodo pubblico / protetto nella classe base che consentirà di accrescere l'evento per voi. Quindi chiamare questo metodo dalla classe derivata.
o
E 'questo quello che vuoi?
public class MyLabel : Label
{
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
//Do derived class stuff here
}
}
Lo stile della finestra WS_EX_TRANSPARENT
esteso in realtà fa questo (che è ciò che in-place tooltip utilizzano). Si potrebbe prendere in considerazione l'applicazione di questo stile, piuttosto che codifica un sacco di gestori a farlo per voi.
Per fare questo, l'override del metodo CreateParams
:
protected override CreateParams CreateParams
{
get
{
CreateParams cp=base.CreateParams;
cp.ExStyle|=0x00000020; //WS_EX_TRANSPARENT
return cp;
}
}
Per ulteriori approfondimenti: