2008-10-21 5 views
2

J'ai dérivé un TabControl dans le but exprès d'activer la double mise en mémoire tampon, sauf que rien ne fonctionne comme prévu. Voici le code TabControl:Double problème de mise en mémoire tampon d'un TabControl dessiné par le propriétaire dérivé?

class DoubleBufferedTabControl : TabControl 
{ 
    public DoubleBufferedTabControl() : base() 
    { 
     this.DoubleBuffered = true; 
     this.SetStyle 
      (
       ControlStyles.UserPaint | 
       ControlStyles.AllPaintingInWmPaint | 
       ControlStyles.ResizeRedraw | 
       ControlStyles.OptimizedDoubleBuffer | 
       ControlStyles.SupportsTransparentBackColor, 
       false 
      ); 
    } 
} 

Ce tabcontrol est ensuite mis avec elle est mode de dessin comme « OwnerDrawnFixed » pour que je puisse changer les couleurs. Voici la méthode de dessin personnalisé:

private void Navigation_PageContent_DrawItem(object sender, DrawItemEventArgs e) 
    { 
     //Structure. 
     Graphics g = e.Graphics; 
     TabControl t = (TabControl)sender; 
     TabPage CurrentPage = t.TabPages[e.Index]; 

     //Get the current tab 
     Rectangle CurrentTabRect = t.GetTabRect(e.Index); 

     //Get the last tab. 
     Rectangle LastTab = t.GetTabRect(t.TabPages.Count - 1); 

     //Main background rectangle. 
     Rectangle BackgroundRect = new Rectangle(LastTab.Width, t.Bounds.Y - 4, t.Width - (LastTab.Width), t.Height); 

     //Tab background rectangle. 
     Rectangle TabBackgroundRect = new Rectangle(0, LastTab.Y + LastTab.Height, LastTab.Width, t.Bounds.Height - (LastTab.Y + LastTab.Height)); 

     //Set anitialiasing for the text. 
     e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; 

     //String format for the text. 
     StringFormat StringFormat = new StringFormat(); 
     StringFormat.Alignment = StringAlignment.Center; 
     StringFormat.LineAlignment = StringAlignment.Center; 

     //Fill the background. 
     g.FillRectangle(Brushes.LightGray, BackgroundRect); 
     g.FillRectangle(Brushes.Bisque, TabBackgroundRect); 

     //Draw the selected tab. 
     if(e.State == DrawItemState.Selected) 
     { 
      g.FillRectangle(Brushes.White, e.Bounds); 
      Rectangle SelectedTabOutline = new Rectangle(e.Bounds.X + 2, e.Bounds.Y + 2, e.Bounds.Width, e.Bounds.Height - 4); 
      g.DrawRectangle(new Pen(Brushes.LightGray, 4f), SelectedTabOutline); 
      g.DrawString(CurrentPage.Text, new Font("Arial", 12f, FontStyle.Bold, GraphicsUnit.Point), new SolidBrush(Color.FromArgb(70, 70, 70)), CurrentTabRect, StringFormat); 
     } 
     else 
     { 
      g.FillRectangle(new SolidBrush(Color.FromArgb(230, 230, 230)), e.Bounds); 
      g.DrawString(CurrentPage.Text, new Font("Arial", 12f, FontStyle.Regular, GraphicsUnit.Point), Brushes.Gray, CurrentTabRect, StringFormat); 
     } 

    } 

Tout cela en vain cependant que ce contrôle ne double buffer et scintille encore quand redimensionnée.

Des idées?

Répondre

2

Si vous lisez la documentation, il est écrit "Ce membre n'est pas significatif pour ce contrôle". Si vous voulez que le contrôle soit dessiné en utilisant le double tampon, vous devrez l'implémenter vous-même. Outre le fait que si vous dessinez le contrôle, vous devrez de toute façon implémenter le double tampon.

0

Vous n'êtes pas sûr, mais vous pouvez essayer de double-buffering le contrôle qui contient le contrôle de tabulation.

0

J'ai regardé un peu autour de moi, j'ai essayé votre code et tout ce que je pouvais penser, mais je ne vois pas de moyen de me débarrasser du scintillement. Malheureusement, dans mes tests, même un contrôle d'onglet régulier (non dessiné par le propriétaire) scintille lors du redimensionnement. Pour ce que ça vaut, éteindre "Afficher le contenu de la fenêtre en faisant glisser" le corrigera, mais je réalise que cela ne sera peut-être pas utile.

+0

oh bien, merci d'avoir essayé. –

0

Je pense que cela ne fonctionne pas parce que vous désactivez le double tampon!

Tous this.DoubleBuffered = true est défini sur ControlStyles.OptimizedDoubleBuffer sur true. Puisque vous désactivez ce drapeau dans la ligne suivante de votre programme, vous ne faites vraiment rien. Supprimer ControlStyles.OptimizedDoubleBuffer (et peut-être ControlStyles.AllPaintingInWmPaint) et il devrait fonctionner pour vous.

2

Tout d'abord, vous pouvez vous débarrasser de votre TabControl code — vous activez la mise en mémoire tampon, puis désactivez-le immédiatement, de sorte qu'il ne fait rien vraiment utile.

Une partie de votre problème est que vous essayez de peindre seulement partie du TabControl.

La solution la plus simple qui donne sur une solution à 90% (il est encore possible d'obtenir un scintillement) est d'ajouter ceci à votre classe de formulaire:

protected override CreateParams CreateParams 
{ 
    get 
    { 
     CreateParams cp = base.CreateParams; 
     cp.ExStyle |= 0x02000000; 
     return cp; 
    } 
} 

Si vous voulez être très sûr d'obtenir Pas de scintillement, vous devrez dessiner l'intégralité de TabControl vous-même, et assurez-vous d'ignorer les demandes de peinture d'arrière-plan.

Editer: Notez que cela ne fonctionnera que sous XP et plus tard.

1

J'ai eu des problèmes avec la double mise en mémoire tampon sur les contrôles dans le passé et la seule façon d'arrêter le scintillement était de m'assurer que la méthode héritée OnPaintBackground n'était pas appelée. (Voir le code ci-dessous) Vous devrez également vous assurer que l'intégralité du fond est peinte pendant votre peinture.

protected override void OnPaintBackground(PaintEventArgs pevent) 
{ 
    //do not call base - I don't want the background re-painted! 
} 
Questions connexes