Reputation: 36639
In my application I have a DataGridView control that displays data for the selected object. When I select a different object (in a combobox above), I need to update the grid. Unfortunately different objects have completely different data, even different columns, so I need to clear all the existing data and columns, create new columns and add all the rows. When this is done, the whole control flickers horribly and it takes ages. Is there a generic way to get the control in an update state so it doesn't repaint itself, and then repaint it after I finish all the updates?
It is certainly possible with TreeViews:
myTreeView.BeginUpdate();
try
{
//do the updates
}
finally
{
myTreeView.EndUpdate();
}
Is there a generic way to do this with other controls, DataGridView in particular?
UPDATE: Sorry, I am not sure I was clear enough. I see the "flickering", because after single edit the control gets repainted on the screen, so you can see the scroll bar shrinking, etc.
Upvotes: 7
Views: 23884
Reputation: 2458
You may also try this, its work.
public static void DoubleBuffered(Control formControl, bool setting)
{
Type conType = formControl.GetType();
PropertyInfo pi = conType.GetProperty("DoubleBuffered", BindingFlags.Instance | BindingFlags.NonPublic);
pi.SetValue(formControl, setting, null);
}
Upvotes: 0
Reputation: 101
People seem to forget a simple fix for this:
Object.Visible = false;
//do update work
Object.Visible = true;
I know it seems weird, but that works. When the object is not visible, it won't redraw itself. You still, however, need to do the begin
and end
update.
Upvotes: 10
Reputation: 71060
Double buffering won't help here since that only double buffers paint operations, the flickering the OP is seeing is the result of multiple paint operations:
so that's four repaints to update the control, hence the flicker. Unfortunately, not all the standard controls have the BeginUpdate/EndUpdate which would remove all the repaint calls until the EndUpdate is called. Here's what you can do:
Options 1 and 2 would still flicker a bit.
On the .Net GUI program I'm working on, I created a set of custom controls that eliminated all flicker.
Upvotes: 8
Reputation: 71060
Rather than adding the rows of the data grid one at a time, use the DataGridView.Rows.AddRange
method to add all the rows at once. That should only update the display once. There's also a DataGridView.Columns.AddRange
to do the same for the columns.
Upvotes: 7
Reputation: 4110
This worked for me.
http://www.syncfusion.com/faq/windowsforms/search/558.aspx
Basically it involves deriving from the desired control and setting the following styles.
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.DoubleBuffer, true);
Upvotes: 2
Reputation: 1110
The .NET control supports the SuspendLayout and ResumeLayout methods. Pick the appropriate parent control (i.e. the control that hosts the controls you want to populate) and do something like the following:
this.SuspendLayout();
// Do something interesting.
this.ResumeLayout();
Upvotes: 9
Reputation: 47873
Unfortunatly, I think that thins might just be a by-product of the .net framework. I am experiencing similar flickering albeit with custom controls. Many of the reference material I have read indicates this, alongside the fact the the double buffering method failed to remove any flickering for me.
Upvotes: 1
Reputation: 15568
Sounds like you want double-buffering:
http://www.codeproject.com/KB/graphics/DoubleBuffering.aspx
Although this is mainly used for individual controls, you can implement this in your Windows Forms control or Form.
Upvotes: 1