Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Suspend Redraw of Windows Form

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?)

like image 843
GWLlosa Avatar asked Feb 25 '09 19:02

GWLlosa


1 Answers

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...
}
like image 196
Corey Ross Avatar answered Sep 24 '22 06:09

Corey Ross