views:

1265

answers:

3

I have a windows form. It contains several datagridviews on it. At some point, the user can press a button which updates the datagridviews. When they do, they can usually sit and watch the datagridview redraw itself, one row at a time. I'd like for the control to not paint until its "done", that is, I'd like a way to tell the control to

Control.SuspendRedraw()
this.doStuff()
this.doOtherStuff()
this.doSomeReallyCoolStuff()
Control.ResumeRedaw()

I've seen the SuspendLayout / ResumeLayout functions, but they do nothing (they seem to be more related to resizing/moving controls, not just editting their datavalues?)

A: 

You can try to set the form to use DoubleBuffer. Set the Form.DoubleBuffer property to true, and this should solve your issue.

Jon
It smoothes out the redraw a little, but you can still see each box being drawn in.
GWLlosa
+4  A: 

There are a couple of things that you can try:

First, try setting the DoubleBuffer property of the DataGridView to true. This is the property on the actual DataGridView instance, not the Form. It's a protected property, so you'll have to sub-class your grid to set it.

class CustomDataGridView: DataGridView
{
    public CustomDataGridView()
    {
        DoubleBuffered = true;
    } 
}

I've seen a lot of small draw updates take a while with the DataGridView on some video cards, and this may solve your problem by batching them up before they are sent off for display.


Another thing you can try is the Win32 message WM_SETREDRAW

// ... this would be defined in some reasonable location ...

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = false)]
static extern IntPtr SendMessage(HandleRef hWnd, Int32 Msg, IntPtr wParam, IntPtr lParam);

static void EnableRepaint(HandleRef handle, bool enable)
{
    const int WM_SETREDRAW = 0x000B;
    SendMessage(handle, WM_SETREDRAW, new IntPtr(enable ? 1 : 0), IntPtr.Zero);
}

Elsewhere in your code you'd have

HandleRef gh = new HandleRef(this.Grid, this.Grid.Handle);
EnableRepaint(gh, false);
try
{
    this.doStuff();
    this.doOtherStuff();
    this.doSomeReallyCoolStuff();
}
finally
{
    EnableRepaint(gh, true);
    this.Grid.Invalidate(); // we need at least one repaint to happen...
}
Corey Ross