Reputation: 20384
My Windows Forms application has a large TabControl to select the view that the user wants to do (customer management, other special list management, log list, etc.). Each tab page contains nothing special, it's just a bunch of standard controls, layouted through TableLayoutPanels and FlowLayoutPanels. These are Labels, TextBoxes, ComboBoxes, ListBoxes and so on.
When I switch the tab page, I can literally watch Windows Forms painting the controls on the screen. In the first moment, the background of some controls seems to be partially painted, then other regions, then text, and a few rendering frames later everything is painted and complete.
There is no event handler on the TabControl so nothing could delay the switching. The tab switching itself is quick, it's just the rendering of stock controls that doesn't happen in one step but progressively. This is something that the user should not see. The controls themselves are also static. I don't re-arrange or dynamically create them at runtime. There doesn't even have to be any content. I can already see this on a new tab page I've just designed and that isn't filled with data yet. I have never seen such partial updates with WPF, it's a WinForms issue.
What could be the cause of this behaviour and what can I do to fix it? Is it possible at all to get atomic screen updates with Windows Forms?
Sometimes I could use SuspendLayout and ResumeLayout, but I don't perform any layout here, so there's no line of code that I could put those calls into. It's the default TabControl behaviour.
Using VS 2010 with .NET 4.0, but this problem exists for years.
Upvotes: 0
Views: 2229
Reputation: 21999
You definetely see layouting process of TableLayoutPanel
and FlowLayoutPanel
combined with not-double-buffered painting.
First one is easy to solve with SuspendLayout()
/ResumeLayout()
. Surround with those your dynamic control adding. If you don't change TableLayoutPanel.Controls collection, then perhaps you still need it for the first draw (this depends on the complicity, too nested containers are problem).
Second one required some tweaking
[System.ComponentModel.DesignerCategory("Code")]
public class XTableLayoutPanel : TableLayoutPanel
{
[DefaultValue(typeof(Color), "Transparent")]
public new Color BackColor
{
get { return base.BackColor; }
set { base.BackColor = value; }
}
public XTableLayoutPanel()
{
// set user paint style
SetStyle(ControlStyles.UserPaint | ControlStyles.ResizeRedraw | ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
BackColor = Color.Transparent;
}
protected override void OnPaint(PaintEventArgs e)
{
// do nothing
}
}
Winform is a problem by itself, containers (which are must for scalable or localizable applications) are not fitting well into its redrawing process. Consider to use WPF for future projects, which has layouting build into redrawing itself (if I can spell it this way).
Upvotes: 1