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 tipo System.Windows.Forms.Control; la qualificazione deve essere di tipo TheProject.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.

È stato utile?

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:

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top