34 Stimmen

Weitergabe von Mausereignissen an das übergeordnete Steuerelement

Umgebung: .NET Framework 2.0, VS 2008.

Ich versuche, eine Unterklasse von bestimmten .NET-Steuerelementen (Label, Panel) zu erstellen, die bestimmte Mausereignisse durchlässt ( MouseDown , MouseMove , MouseUp ) an sein übergeordnetes Steuerelement (oder alternativ an das übergeordnete Formular). Ich kann dies tun, indem ich Handler für diese Ereignisse in Instanzen der Standardsteuerelemente erstelle, z. B.:

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);
    }
}

Ich kann den Event-Handler nicht in eine Unterklasse des Steuerelements verschieben, da die Methoden, die die Ereignisse im übergeordneten Steuerelement auslösen, geschützt sind und ich keinen Qualifier für das übergeordnete Steuerelement habe:

Zugriff auf geschütztes Mitglied nicht möglich System.Windows.Forms.Control.OnMouseDown(System.Windows.Forms.MouseEventArgs) über einen Qualifier des Typs System.Windows.Forms.Control ; der Qualifier muss vom Typ TheProject.NoCaptureLabel (oder von ihr abgeleitet).

Ich überprüfe die Überschreibung der WndProc Methode des Steuerelements in meiner Unterklasse, aber hoffentlich kann mir jemand eine sauberere Lösung geben.

70voto

akatran Punkte 1017

Ja. Nach langem Suchen fand ich den Artikel "Schwebende Steuerelemente, Tooltip-Stil" , die die WndProc um die Nachricht von WM_NCHITTEST まで HTTRANSPARENT , wodurch die Control transparent für Mausereignisse.

Um dies zu erreichen, erstellen Sie ein Steuerelement, das von Label und fügen Sie einfach den folgenden Code ein.

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);
    }
}

Ich habe dies in Visual Studio 2010 mit .NET Framework 4 Client Profile getestet.

5voto

Jeff Yates Punkte 59874

Le site WS_EX_TRANSPARENT erweitertes Fenster Stil tatsächlich tut dies (es ist, was in-Place-Tooltips verwenden). Vielleicht möchten Sie die Anwendung dieses Stils in Betracht ziehen, anstatt viele Handler zu kodieren, die dies für Sie erledigen.

Um dies zu tun, überschreiben Sie die CreateParams Methode:

protected override CreateParams CreateParams
{
  get
  {
    CreateParams cp=base.CreateParams;
    cp.ExStyle|=0x00000020; //WS_EX_TRANSPARENT
    return cp;
  }
}

Für weitere Informationen:

2voto

Autodidact Punkte 27160

Sie müssen eine öffentliche/geschützte Methode in Ihrer Basisklasse schreiben, die das Ereignis für Sie auslöst. Rufen Sie diese Methode dann in der abgeleiteten Klasse auf.

OR

Ist es das, was Sie wollen?

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X