Paso a través de eventos de ratón para el control de los padres
-
23-08-2019 - |
Pregunta
Medio Ambiente: .NET Framework 2.0, VS 2008
. Estoy intentando crear una subclase de ciertos controles .NET (etiqueta, panel) que pasarán a través de ciertos eventos de ratón (MouseDown
, MouseMove
, MouseUp
) a su control principal (o alternativamente a la forma de nivel superior). Puedo hacer esto mediante la creación de los manipuladores para estos eventos en los casos de los controles estándar, por ejemplo:.
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);
}
}
No se puede mover el controlador de eventos en una subclase del control, debido a que los métodos que elevan los eventos en el control de los padres están protegidos y no tengo un partido de clasificación para el control de los padres:
No se puede acceder a través protegida
System.Windows.Forms.Control.OnMouseDown(System.Windows.Forms.MouseEventArgs)
miembro de un partido de clasificación del tipoSystem.Windows.Forms.Control
; el calificador debe ser de tipoTheProject.NoCaptureLabel
(o derivada de ella).
Estoy buscando en la sustitución del método WndProc
del control en mis sub-clase, pero espero que alguien me puede dar una solución más limpia.
Solución
Sí. Después de mucho buscar, encontré el artículo "Controles flotantes, información sobre herramientas de estilo" , que utiliza WndProc
para cambiar el mensaje de WM_NCHITTEST
a HTTRANSPARENT
, haciendo que el Control
transparente a eventos de ratón.
Para lograr eso, crear un control heredado de Label
y simplemente añadir el siguiente código.
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);
}
}
He probado esto en Visual Studio 2010 con .NET Framework 4 Client Profile.
Otros consejos
Usted tiene que escribir un método público / protegidos en su clase base que elevará el evento para usted. Entonces llamar a este método de la clase derivada.
o
¿Es esto lo que quieres?
public class MyLabel : Label
{
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
//Do derived class stuff here
}
}
El estilo de ventana extendido WS_EX_TRANSPARENT
realmente hace esto (que es lo que en el lugar sobre herramientas utilizan). Es posible que desee considerar la aplicación de este estilo en lugar de la codificación de una gran cantidad de controladores que lo haga por usted.
Para ello, reemplazar el método CreateParams
:
protected override CreateParams CreateParams
{
get
{
CreateParams cp=base.CreateParams;
cp.ExStyle|=0x00000020; //WS_EX_TRANSPARENT
return cp;
}
}
Para la lectura adicional: