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 tipo System.Windows.Forms.Control; el calificador debe ser de tipo TheProject.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.

¿Fue útil?

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:

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top