Question

Environnement: .NET Framework 2.0, VS 2008

.

Je suis en train de créer une sous-classe de certains contrôles .NET (étiquette, panneau), qui passera par certains événements de souris (MouseDown, MouseMove, MouseUp) à son contrôle parent (ou bien à la forme de haut niveau). Je peux le faire en créant des gestionnaires pour ces événements dans les cas des contrôles standard, par exemple:.

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

Je ne peux pas déplacer le gestionnaire d'événements dans une sous-classe du contrôle, parce que les méthodes qui soulèvent les événements dans le contrôle des parents sont protégés et je ne dispose pas d'un match de qualification pour le contrôle parent:

  

Impossible d'accéder System.Windows.Forms.Control.OnMouseDown(System.Windows.Forms.MouseEventArgs) membre protégé par une qualification de type System.Windows.Forms.Control; le qualificatif doit être de type TheProject.NoCaptureLabel (ou dérivé de celui-ci).

Je cherche en redéfinissant la méthode WndProc du contrôle dans mon sous-classe, mais nous espérons que quelqu'un peut me donner une solution plus propre.

Était-ce utile?

La solution

Oui. Après beaucoup de recherches, je trouve l'article « Contrôles flottants, style infobulle » , qui utilise WndProc pour modifier le message de WM_NCHITTEST à HTTRANSPARENT, ce qui rend le Control transparent aux événements de souris.

Pour cela, créer un contrôle hérité de Label et il suffit d'ajouter le code suivant.

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

Je l'ai testé dans Visual Studio 2010 avec .NET Framework 4 Client Profile.

Autres conseils

Vous devez écrire une méthode publique / protégée dans la classe de base qui soulèvera l'événement pour vous. Ensuite, appelez cette méthode de la classe dérivée.

ou

Est-ce que vous voulez?

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

Le style de fenêtre WS_EX_TRANSPARENT étendue ne fait cela (c'est ce que infobulles en place utilisent). Vous voudrez peut-être envisager d'appliquer ce style plutôt que de coder beaucoup de gestionnaires à faire pour vous.

Pour ce faire, passer outre la méthode CreateParams:

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

Pour en savoir plus:

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top