At my previous job, we struggled with getting our rich UI app to paint instantly and smoothly. We were using standard .Net controls, custom controls and devexpress controls.
After a lot of googling and reflector usage, I came across the WM_SETREDRAW win32 message. This really stops controls drawing whilst you update them and can be applied, IIRC to the parent/containing panel.
This is a very very simple class demonstrating how to use this message:
class DrawingControl { [DllImport("user32.dll")] public static extern int SendMessage(IntPtr hWnd, Int32 wMsg, bool wParam, Int32 lParam); private const int WM_SETREDRAW = 11; public static void SuspendDrawing( Control parent ) { SendMessage(parent.Handle, WM_SETREDRAW, false, 0); } public static void ResumeDrawing( Control parent ) { SendMessage(parent.Handle, WM_SETREDRAW, true, 0); parent.Refresh(); } }
There are fuller discussions on this - google for C# and WM_SETREDRAW, e.g.
And to whom it may concern, this is a similar example in VB:
Public Module Extensions <DllImport("user32.dll")> Private Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As Integer, ByVal wParam As Boolean, ByVal lParam As IntPtr) As Integer End Function Private Const WM_SETREDRAW As Integer = 11 ' Extension methods for Control <Extension()> Public Sub ResumeDrawing(ByVal Target As Control, ByVal Redraw As Boolean) SendMessage(Target.Handle, WM_SETREDRAW, True, IntPtr.Zero) If Redraw Then Target.Refresh() End If End Sub <Extension()> Public Sub SuspendDrawing(ByVal Target As Control) SendMessage(Target.Handle, WM_SETREDRAW, False, IntPtr.Zero) End Sub <Extension()> Public Sub ResumeDrawing(ByVal Target As Control) ResumeDrawing(Target, True) End Sub End Module