2009-02-13 7 views
29

Medio Ambiente: .NET Framework 2.0, VS 2008.de Transmisión a través de eventos de ratón para el control de los padres

Estoy intentando crear una subclase de ciertos controles .NET (etiqueta, el panel) que pasarán a través de ciertos eventos de ratón (MouseDown, MouseMove, MouseUp) a su control principal (o alternativamente al formulario de nivel superior). Puedo hacer esto mediante la creación de controladores de 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 puedo 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 tener un partido de clasificación para el control de los padres:

no se puede acceder miembro protegido System.Windows.Forms.Control.OnMouseDown(System.Windows.Forms.MouseEventArgs) a través de un calificador de tipo System.Windows.Forms.Control; el calificador debe ser del tipo TheProject.NoCaptureLabel (o derivado de él).

Estoy buscando en la sustitución del método del control WndProc en mis sub-clase, pero espero que alguien me puede dar una solución más limpia.

+0

¿Es ese el mensaje de error correcto para este código? Uno es MouseUp y el otro es MouseDown. –

+0

Tampoco me queda claro a qué te refieres con "pasar". –

+0

El mensaje de error es incorrecto, debería ser MouseDown. Lo que quiero decir con "paso directo" es que, cuando se generan ciertos eventos en un control, los crío de forma programática en el elemento primario del control. – GentlemanCoder

Respuesta

55

Sí. Después de mucha búsqueda, encontré el artículo "Floating Controls, tooltip-style", que usa WndProc para cambiar el mensaje de WM_NCHITTEST a HTTRANSPARENT, haciendo que el Control sea transparente para los eventos del mouse.

Para lograr eso, crea un control heredado de Label y simplemente agrega 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.

+0

Gracias akatran-- He avanzado tanto que ni siquiera recuerdo cómo resolví este problema yo mismo, pero parece que lo has enganchado. – GentlemanCoder

+0

Muchas gracias, esto también me ha ayudado, ¡es claro, conciso y resuelve el problema! – Eric

+1

Vale la pena señalar que esto saca los falsos controles transparentes del bucle de eventos; no tienen la posibilidad de manejar el evento MouseMove porque se conecta directamente con el controlador del padre. Para conservar la capacidad de que cada control en sí mismo también maneje el evento antes de pasarlo al padre, puede hacer algo como esto: http://stackoverflow.com/a/14814756/327083 –

3

Necesita escribir un método público/protegido en su clase base que le planteará el evento. Luego llama a este método desde la clase derivada.

O

¿Esto es lo que quieres?

public class MyLabel : Label 
{ 
    protected override void OnMouseDown(MouseEventArgs e) 
    { 
     base.OnMouseDown(e); 
     //Do derived class stuff here 
    } 
} 
+0

No lo creo. OnMouseDown * plantea * el evento, no lo maneja. Necesito un controlador de eventos que pase el evento a su padre. Y no puedo hacer su primera sugerencia, porque la clase base es un control estándar de Windows, no una clase que escribí. – GentlemanCoder

+0

@GentlemanCoder ¿realmente has probado esto? –

+0

@SandeepDatta, el control principal y la clase base son diferentes, ¿verdad? – Kira

3

El estilo de ventana extendido WS_EX_TRANSPARENT realidad tiene 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 codificar muchos manipuladores para que lo hagan por usted.

Para ello, anular 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:

+1

Gracias por la sugerencia. Lo intenté y no funciona en mi caso. Tal vez solo funciona para ventanas de nivel superior? – GentlemanCoder

Cuestiones relacionadas