How do I suspend painting for a control and its children?
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.
Suspending Painting for a Control and Its Children
When updating multiple UI elements at once, each individual change can trigger a repaint of the control. This causes visible flickering and wastes CPU cycles on intermediate states the user never needs to see. Suspending painting lets you batch all updates together so the control redraws only once, showing the final result.
This technique is most commonly needed in Windows Forms, but the concept applies to other UI frameworks as well. This article covers practical approaches in Windows Forms with working C# code, plus brief notes on WPF and web development equivalents.
Why Suspend Painting?
Every time you modify a property of a Windows Forms control (adding items to a ListBox, changing cell values in a DataGridView, repositioning child controls), the framework sends a WM_PAINT message that triggers a redraw. When you make dozens of changes in rapid succession, the user sees each intermediate state as a brief flicker.
Suspending painting addresses three problems:
- Visual flickering. The control does not repaint until you explicitly resume, so the user sees only the final state.
- Performance. Skipping intermediate repaints saves significant time when updating many elements.
- UI consistency. The user never sees a half-updated control where some elements reflect new data and others do not.
Method 1: SuspendLayout and ResumeLayout
The simplest built-in approach is SuspendLayout and ResumeLayout. These methods prevent the control from recalculating layout for its children until you are done making changes:
SuspendLayout stops layout recalculation but does not fully suppress painting. Controls may still repaint individually as they are added. For full paint suppression, use the WM_SETREDRAW message.
Method 2: WM_SETREDRAW Message (Full Paint Suppression)
Sending the WM_SETREDRAW Windows message to a control completely disables or enables painting. This is the most effective way to eliminate flickering:
Usage:
The finally block is critical. If an exception occurs during updates and you forget to resume drawing, the control will remain invisible until the application is closed or the message is sent again.
Method 3: BeginUpdate and EndUpdate
Several built-in controls like ListBox, ListView, TreeView, and ComboBox have their own BeginUpdate and EndUpdate methods that suspend painting:
These methods are optimized for their specific controls and handle the WM_SETREDRAW message internally. Always prefer BeginUpdate/EndUpdate when the control supports it.
Method 4: Double Buffering
Double buffering draws the control to an off-screen buffer first, then copies the entire buffer to the screen in one operation. This eliminates flickering without needing to suspend and resume painting:
You can also enable double buffering on existing controls using reflection:
Double buffering reduces flickering during normal painting but does not address the performance cost of layout recalculation during bulk updates. For large batch operations, combine double buffering with SuspendLayout or WM_SETREDRAW.
A Reusable IDisposable Pattern
Wrapping the suspend/resume logic in an IDisposable ensures that painting is always resumed, even if an exception occurs:
Usage:
Notes for Other Frameworks
WPF uses retained-mode rendering, so manual paint suspension is rarely needed. If you do need to batch visual updates, use Dispatcher.BeginInvoke with a lower priority or call InvalidateVisual() only after all changes are complete.
Web development handles this differently. Browsers batch DOM mutations and repaint once per frame. However, reading layout properties (like offsetWidth) between DOM writes forces a synchronous reflow. Avoid interleaving reads and writes. The CSS property will-change and the requestAnimationFrame API help optimize rendering performance.
Common Pitfalls
- Forgetting to resume drawing. Always wrap suspend/resume in a try-finally or IDisposable. A control left in the suspended state will appear blank.
- Calling Refresh vs Invalidate.
Refreshforces an immediate synchronous repaint.Invalidatequeues a repaint for the next message loop iteration. After resuming drawing,Refreshis usually the right choice to guarantee an immediate update. - Nesting suspend calls.
WM_SETREDRAWis not reference-counted. Sendingtrueonce will enable painting regardless of how manyfalsemessages were sent. Avoid nesting suspend/resume calls across different methods. - Thread safety. UI controls must be updated from the UI thread. Calling
SuspendDrawingfrom a background thread can cause handle-creation errors or deadlocks. - Confusing SuspendLayout with SuspendDrawing.
SuspendLayoutonly prevents layout recalculation. It does not stop the control from repainting. For full flicker elimination, useWM_SETREDRAW.
Summary
Suspending painting prevents a control from redrawing during batch updates, eliminating flickering and improving performance. For controls that support it, use BeginUpdate/EndUpdate. For general controls in Windows Forms, send the WM_SETREDRAW message via P/Invoke, and always resume painting in a finally block or IDisposable wrapper. Combine this with SuspendLayout to also skip layout recalculation, and consider enabling double buffering for smooth rendering during normal use. The key rule is to always ensure painting is resumed, regardless of whether the update code succeeds or throws an exception.
Related reading
- How do I time a method's execution in Java?
- How do I trim whitespace?
- How do I trim whitespace?
- How do I trim whitespace from a string?
- How do I type hint a method with the type of the enclosing class?
- How do I use a dump file to diagnose a memory leak?
- How do I use TTL on clickhouse table?
- How do I write a correct micro-benchmark in Java?

DSA Fundamentals
Master algorithmic patterns and data structures through hands-on LeetCode-style problems - from arrays and hashing to dynamic programming and advanced graphs.
View the courseTrack what you have practised
A free account saves your progress, solutions and study plan across every problem on Codemia.
Data Structures & Algorithms practice on Codemia
Step through 300 algorithm problems with animated visualisers that show the data structure changing as the code runs.