Frage

ich eine TabControl mit dem ausdrücklichen Ziel abgeleitet habe doppelte Pufferung zu ermöglichen, mit der Ausnahme nichts funktioniert wie erwartet. Hier ist der TabControl Code:

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

Dieses tabcontrol dann gesetzt damit Modus ist ziehen als ‚OwnerDrawnFixed‘, so kann ich die Farben geändert. Hier ist die kundenspezifische Zeichnungsmethode:

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

    }

Alle jedoch ohne Erfolg, da diese Kontrolle nicht gepuffert ist doppelt und flackert immer noch, wenn die Größe verändert.

Irgendwelche Ideen?

War es hilfreich?

Lösung

Wenn Sie die Dokumentation lesen, heißt es: „Dieses Mitglied ist für diese Kontrolle nicht sinnvoll.“ Wenn Sie die Kontrolle wollen Double-Buffering zu erstellenden verwendet, müssen Sie es selbst implementieren. Neben der Tatsache, dass, wenn Sie die Steuerinhaber ziehen, müßten Sie selbst implementieren sowieso doppelt gepuffert werden.

Andere Tipps

Zunächst einmal können Sie Ihre TabControl loszuwerden Code Sie auf Pufferung drehen, und dann sofort deaktivieren, so ist es nicht wirklich etwas Nützliches zu tun.

Ein Teil des Problems ist, dass Sie versuchen, nur zu malen Teil des TabControl.

Die einfachste Lösung, um eine 90% ige Lösung gibt (es ist immer noch möglich, ein Flimmern zu bekommen) ist dies auf dem Formular Klasse hinzuzufügen:

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

Wenn Sie auf sehr sicher kein Flimmern zu bekommen, werden Sie den gesamten TabControl sich ziehen müssen, und stellen Sie sicher, Hintergrund Malerei Anfragen zu ignorieren.

Edit:. Beachten Sie, dass dies nur in XP arbeiten und später

Ich habe Probleme mit doppelter Pufferung auf Kontrollen in der Vergangenheit habe und den einzigen Weg, um das Flimmern zu stoppen war die geerbte OnPaintBackground Methode, um sicherzustellen, wurde nicht genannt zu werden. (Siehe Code unten) Sie werden auch die gesamte backgound während Ihrer Farbe Anruf gemalt gewährleisten müssen.

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

Nicht sicher, aber Sie könnten versuchen, Double-Buffering das Steuerelement, das auf die Registerkarte Steuerelement enthält.

Ich sah mich um einiges versucht, Ihren Code und was sonst ich denken konnte, aber ich sehe nicht ein Weg des Flimmern loszuwerden. Leider ist in meinen Tests auch eine regelmäßige (nicht eigentümer gezeichnet) Registerkarte flackert während einer Größenänderung.

Für das, was es wert ist, ausschalten „Fensterinhalt beim Ziehen anzeigen“ wird es beheben, aber ich merke, dass nicht hilfreich sein kann.

Ich denke, es funktioniert nicht, weil Sie doppelte Pufferung deaktivieren!

Alle this.DoubleBuffered = true nicht gesetzt ControlStyles.OptimizedDoubleBuffer auf true. Da Sie diese Fahne in der nächsten Zeile Ihres Programms zu deaktivieren, tun Sie wirklich nichts. Entfernen ControlStyles.OptimizedDoubleBuffer (und vielleicht ControlStyles.AllPaintingInWmPaint) und es sollte für Sie arbeiten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top