2009-04-16 8 views
0

J'ai écrit ce qui suit (très simple) commande pour une utilisation dans une application (commentaires supprimés par souci de concision):Qu'est-ce que je fais de mal avec mon contrôle "HorizontalRule" personnalisé?

public partial class HorizontalRule : Control 
{ 
    public HorizontalRule() 
    { 
     InitializeComponent(); 
    } 

    protected override void OnPaint(PaintEventArgs e) 
    { 
     base.OnPaint(e); 

     var g = e.Graphics; 

     var rect = new Rectangle(
      this.ClientRectangle.Left, 
      this.ClientRectangle.Height/2 + 1, 
      this.ClientRectangle.Width, 
      1); 

     ControlPaint.DrawBorder3D(g, rect, Border3DStyle.Etched); 

     return; 
    } 
} 

Disclaimer: Je suis un débutant à la peinture mes propres contrôles.

J'ai choisi de dessiner la ligne de cette façon en fonction du recommendation in the Vista UX guidelines qui suggère un rectangle gravé de hauteur 1 pour les séparateurs.

Lorsque cela est statique, cela semble bien, mais j'ai remarqué que je devrais redessiner les artefacts si je place ce contrôle dans une fenêtre et le redimensionner (via l'ancre, par exemple). Je redessine ma bordure sur toute la largeur de mon rectangle client, mais c'est comme si elle n'était pas réellement peinte. Activer DoubleBuffered dans le constructeur de HorizontalRule, ou sous la forme dans laquelle il est incorporé, ne semble pas non plus faire la différence.

Qu'est-ce que je fais mal?

Mise à jour:

par la suggestion, j'ai essayé d'appeler base.OnPaint dernier au lieu de la première. Je ne sais pas ce que cela aurait changé, et cela ne semble pas avoir changé non plus.

Ne pas dessiner l'arrière-plan n'a rien donné d'utile. Je reçois toujours l'artefact, mais je n'obtiens pas la couleur d'arrière-plan alors à la place j'ai vu l'image de ce qui se trouvait sous la ligne horizontale.

Répondre

1

Je peux pirater une solution qui ne donne pas lieu à artifacting en remplaçant OnResize() pour invalider le contrôle entier:

protected override void OnResize(EventArgs e) 
{ 
    base.OnResize(e); 

    this.Invalidate(); 
} 

Je ne suis pas sûr que ce soit la solution « bonne », cependant.

+0

Ah, bon endroit :) – leppie

0

Je dessinerais ceci sur un bitmap puis dessinerais le bitmap au lieu de me soucier de le peindre à chaque fois.

+0

Que voulez-vous dire? Peindre la bordure sur un bitmap une fois la première fois que le contrôle est affiché, puis étirer juste ce bitmap sur la largeur du contrôle? –

+0

Cela pourrait fonctionner, ce à quoi je faisais allusion était la mise en cache. –

1

Ne pas appeler base.OnPaint, ou l'appeler en dernier (je ne peux pas rappeler maintenant).

Également, essayez de remplacer la méthode de peinture d'arrière-plan afin qu'elle n'appelle pas la base.

+0

Ne pas dessiner l'arrière-plan serait certainement un début –

+0

Ces étapes n'ont rien donné d'utile. :( –

Questions connexes