Re: Flicker In TabControl
Hello,
That's a really old thread, but I'm having the same problem and I already loosed more than an hour on that. I've try many things but without success. I don't know if somebody managed to solve that without using another library or rewriting the tabcontrol, but here is my temporary working solution for now:
1 - put the webcontrol (or other control that cause flickering) somewhere in your form (but not docked and child of the tabpanel).
2 - create functions for the OnResize and OnTabChanged event of the tab control
* In the OnResize, set the width and height of your webcontrol according to the new values of the tabcontrol. You might need to tweak some values since the tabcontrol size is bigger than the desired size.
* In the OnTabChanged, show/hide when the proper tab is displayed.
After that, the resize works like a charm. That's probably one of the biggest patch I've made so far with C# in order to have a decent UI. I don't know why this control is buggy, but I think MS should really fix that.
Re: Flicker In TabControl
As stated in the previous post, this is an old thread, but my solution is new :-). Took a couple hours of poking, but here it is:
For the TabControl replacement:
Code:
using System;
namespace System.Windows.Forms
{
class DoubleBufferedTabControl : System.Windows.Forms.TabControl
{
public DoubleBufferedTabControl()
{
this.SetStyle(ControlStyles.UserPaint | ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
}
protected override void OnPaint(PaintEventArgs pevent)
{
this.SetStyle(ControlStyles.UserPaint, false);
base.OnPaint(pevent);
System.Drawing.Rectangle o = pevent.ClipRectangle;
System.Drawing.Graphics.FromImage(buffer).Clear(System.Drawing.SystemColors.Control);
if (o.Width > 0 && o.Height > 0)
DrawToBitmap(buffer, new System.Drawing.Rectangle(0, 0, Width, o.Height));
pevent.Graphics.DrawImageUnscaled(buffer, 0, 0);
this.SetStyle(ControlStyles.UserPaint, true);
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
buffer = new System.Drawing.Bitmap(Width, Height);
}
private System.Drawing.Bitmap buffer;
}
}
For the TabPage you will also need:
Code:
using System;
namespace System.Windows.Forms
{
class DoubleBufferedTabPage : System.Windows.Forms.TabPage
{
public DoubleBufferedTabPage()
{
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint |ControlStyles.DoubleBuffer, true);
}
}
}
The UserPaint style must be on for OnPaint to be called. In the middle of OnPaint, the UserPaint style is removed allowing it to be drawn as normal. To actually get this drawing, though, we need to force another immediate paint. To do this it is rendered to a bitmap and then drawn on the screen. To finish, UserPaint is set again. This method brought flicker down to a negligible level for me. The only disadvantage I've found is that it is slower, especially when no theming is applied (old Win95 look). The easiest way to use it, is to design your tabs using the regular classes and then use a Search/Replace to change the class names.
I dunno if .Net 3.0 fixes this, but hope this helps somebody!
Re: Flicker In TabControl
Again, even older still but I ran into this with VS2008
That code fixed it! I'm now going to do the same for my slider control instead of hiding it and showing it again when the resize stops.
I translated it into VB.NET in case anyone needs it.
I also finally caught on to the fact that the control needed to be redefined in the form.designer.vb file as the new DoubleBuffedTabControl and DoubleBufferedTabPage instead of the default system.windows.forms.tabcontrol.
Code:
Class DoubleBufferedTabControl
Inherits System.Windows.Forms.TabControl
Public Sub New()
Me.SetStyle(ControlStyles.UserPaint Or ControlStyles.DoubleBuffer Or ControlStyles.AllPaintingInWmPaint, True)
End Sub
Protected Overrides Sub OnPaint(ByVal pevent As PaintEventArgs)
Me.SetStyle(ControlStyles.UserPaint, False)
MyBase.OnPaint(pevent)
Dim o As System.Drawing.Rectangle = pevent.ClipRectangle
System.Drawing.Graphics.FromImage(buffer).Clear(System.Drawing.SystemColors.Control)
If o.Width > 0 AndAlso o.Height > 0 Then
DrawToBitmap(buffer, New System.Drawing.Rectangle(0, 0, Width, o.Height))
End If
pevent.Graphics.DrawImageUnscaled(buffer, 0, 0)
Me.SetStyle(ControlStyles.UserPaint, True)
End Sub
Protected Overrides Sub OnResize(ByVal e As EventArgs)
MyBase.OnResize(e)
buffer = New System.Drawing.Bitmap(Width, Height)
End Sub
Private buffer As System.Drawing.Bitmap
End Class
Class DoubleBufferedTabPage
Inherits System.Windows.Forms.TabPage
Public Sub New()
Me.SetStyle(ControlStyles.AllPaintingInWmPaint Or ControlStyles.UserPaint Or ControlStyles.DoubleBuffer, True)
End Sub
End Class
Re: Flicker In TabControl
This is in C# :
Code:
using Microsoft.VisualBasic;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Diagnostics;
class DoubleBufferedTabControl : System.Windows.Forms.TabControl
{
public DoubleBufferedTabControl()
{
this.SetStyle(ControlStyles.UserPaint | ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
}
protected override void OnPaint(PaintEventArgs pevent)
{
this.SetStyle(ControlStyles.UserPaint, false);
base.OnPaint(pevent);
System.Drawing.Rectangle o = pevent.ClipRectangle;
System.Drawing.Graphics.FromImage(buffer).Clear(System.Drawing.SystemColors.Control);
if (o.Width > 0 && o.Height > 0) {
DrawToBitmap(buffer, new System.Drawing.Rectangle(0, 0, Width, o.Height));
}
pevent.Graphics.DrawImageUnscaled(buffer, 0, 0);
this.SetStyle(ControlStyles.UserPaint, true);
}
protected override void OnResize(EventArgs e)
{
base.OnResize(e);
buffer = new System.Drawing.Bitmap(Width, Height);
}
private System.Drawing.Bitmap buffer;
}
class DoubleBufferedTabPage : System.Windows.Forms.TabPage
{
public DoubleBufferedTabPage()
{
this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.DoubleBuffer, true);
}
}
Not sure if it works, will see later on