Question

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:

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

Ce contrôle de tabulation est ensuite défini avec son mode de dessin comme 'OwnerDrawnFixed' afin 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 en vain cependant, car ce contrôle n'est pas en double tampon et scintille quand il est redimensionné.

Des idées?

Était-ce utile?

La solution

Si vous lisez la documentation, il est indiqué: "Ce membre n'a pas de signification pour ce contrôle." Si vous voulez que le contrôle soit dessiné en utilisant la double mise en tampon, vous devrez l'implémenter vous-même. Outre le fait que si vous contrôlez le contrôle par le propriétaire, vous devrez de toute façon implémenter le double tampon.

Autres conseils

Tout d'abord, vous pouvez vous débarrasser de votre code TabControl : vous activez la mise en mémoire tampon, puis vous l'éteignez immédiatement afin qu'il ne fasse rien d'utile.

Une partie de votre problème tient au fait que vous essayez de ne peindre qu'une partie de TabControl .

La solution la plus simple pour une solution à 90% (il est toujours possible d'obtenir un scintillement) consiste à l'ajouter à 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 de ne pas scintiller, vous devez dessiner vous-même le TabControl et assurez-vous d'ignorer les demandes de peinture en arrière-plan.

Modifier: Notez que cela ne fonctionnera que sous XP et versions ultérieures.

J'ai déjà eu des problèmes de double tampon sur les contrôles et le seul moyen d'arrêter le scintillement était de s'assurer que la méthode OnPaintBackground héritée n'était pas appelée. (Voir le code ci-dessous) Vous devrez également vous assurer que tout le fond est peint pendant votre appel de peinture.

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

Pas sûr, mais vous pouvez essayer de mettre en double tampon le contrôle qui contient le contrôle de tabulation.

J'ai beaucoup regardé autour de moi, essayé votre code et tout ce à quoi je pouvais penser, mais je ne vois pas le moyen de supprimer le scintillement. Malheureusement, dans mes tests, même un contrôle d'onglet standard (non créé par le propriétaire) scintille pendant le redimensionnement.

Pour ce que cela vaut, désactivez & Show; Afficher le contenu de la fenêtre en faisant glisser " résoudra le problème, mais je réalise que cela pourrait ne pas être utile.

Je pense que cela ne fonctionne pas car vous désactivez la double mise en mémoire tampon!

Tout this.DoubleBuffered = true fait est de définir ControlStyles.OptimizedDoubleBuffer sur true. Puisque vous désactivez cet indicateur dans la ligne suivante de votre programme, vous ne faites vraiment rien. Supprimez ControlStyles.OptimizedDoubleBuffer (et peut-être ControlStyles.AllPaintingInWmPaint) et tout devrait fonctionner pour vous.

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