For custom visuals in WinForms, draw in the control’s paint lifecycle—not in a one-off drawing call—and dispose the graphics resources your code creates. Start with framework double buffering if multi-step painting flickers, and specify an image destination rectangle when its displayed size matters. The right DPI and platform guidance depends on whether your app targets modern .NET or .NET Framework.
Where should WinForms drawing code go?
A control raises its Paint event when it needs to update its display. For a control you author, override OnPaint and draw through the Graphics object supplied by PaintEventArgs. The event arguments also provide a ClipRectangle, the region being painted. For an existing control, handle its Paint event instead.
As an Amazon Associate I earn from qualifying purchases.
Drawing that must be present whenever the control is repainted belongs in that paint path. Control.CreateGraphics() can obtain a graphics object for drawing, but a drawing operation performed outside painting is not a substitute for code that reproduces the visual during a later paint.
Illustrative custom-control pattern
This example draws a rectangle and disposes the Pen it creates. Adapt the base-painting behavior to the control you are implementing.
#1 Best Overall
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
using (var pen = new Pen(Color.DodgerBlue, 2))
{
e.Graphics.DrawRectangle(pen, 10, 10, 120, 60);
}
}
e.Graphics is provided for the paint callback; this example does not dispose it. The using scope instead disposes the pen when drawing is finished.
Why does drawing disappear, and how should graphics objects be managed?
Graphics resources are not just ordinary values: Microsoft identifies Graphics, Brush, and Pen instances as objects that consume system resources. Create owned resources when needed and dispose them when finished if they implement IDisposable. In paint code, short-lived pens and brushes commonly fit naturally in a using scope.
Rank #2
- Framework-provided: use the paint callback’s
e.Graphicsfor that callback; do not dispose this borrowed object. - Created by your code: dispose owned pens, brushes, and graphics objects when you are done with them.
- Visual must be reproducible: put the drawing logic in the paint path so it can render when the control paints.
How do you reduce WinForms drawing flicker?
Flicker can be visible when a complex paint operation consists of several drawing steps. Double buffering renders those operations to a memory buffer and then copies the completed buffer to the screen, which can remove flicker caused by the intermediate steps.
Free tools Windows power users keep installed
One-click scans. No signup required.
Start with built-in buffering
For ordinary cases, use the framework’s built-in double-buffering behavior. An authored control can enable the protected DoubleBuffered property or use OptimizedDoubleBuffer through SetStyle. Microsoft Learn’s guidance says, “For most applications, the default double buffering provided by the .NET Framework will provide the best results.” This is implementation guidance, not a benchmark or a guarantee for every workload.
When to manage buffers yourself
Manual BufferedGraphics management is an advanced option when animation or specific buffer and memory control calls for it. It adds complexity; begin with framework buffering unless you have a concrete reason to take over buffer management. Buffering is not a promise that every visual artifact will disappear or that every application will become faster.
Why can a drawn image appear at an unexpected size?
Some DrawImage convenience overloads can automatically scale an image when its resolution metadata differs from the resolution GDI+ uses. Microsoft’s guidance describes 96 DPI as the usual result when GDI+ queries a screen device context; that describes the documentation’s stated context, not a universal measurement of every modern display.
When the intended displayed dimensions matter, specify a destination rectangle explicitly. That makes the requested drawing bounds clear rather than relying on automatic scaling behavior. Image sizing in a drawing call is also distinct from how WinForms scales the rest of a form and its controls for the application’s DPI-awareness mode.
The Tool Desk
Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Which DPI guidance applies to your WinForms target?
Check the application’s target framework and DPI configuration before applying a setting: WinForms DPI configuration differs between modern .NET and .NET Framework, and behavior has changed across releases.
Modern .NET WinForms
Microsoft’s automatic-scaling guidance for modern .NET WinForms identifies the project property ApplicationHighDpiMode as the configuration point, with SystemAware described there as the default and recommended mode. The documentation also describes PerMonitor and PerMonitorV2 modes and DPI-change events. Choose and validate the mode for the application’s needs rather than assuming that an image’s DPI metadata determines form scaling.
.NET 6 and later release-specific behavior
The .NET 6 WinForms release notes describe improved PerMonitorV2 scaling for container controls and MDI child windows. That is a release-specific statement, not a guarantee that all DPI behavior is identical across later versions or configurations. Consult the guidance for the exact runtime you target before making claims about its current defaults.
.NET Framework
Do not apply modern .NET’s project-property instructions as if they were the configuration method for .NET Framework. Microsoft documents the two frameworks’ DPI configuration differently; use the guidance for the framework and application configuration you actually ship.
Quick wins for a faster PC:
Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Can a WinForms GDI+ application run outside Windows?
System.Drawing.Common is Windows-specific starting with .NET 6. Microsoft’s compatibility guidance says that non-Windows use can produce platform-analysis warnings and, without the legacy runtime switch described on that page, a PlatformNotSupportedException. The temporary switch described for that transition should not be treated as a current cross-platform support contract.
For a cross-platform drawing requirement, Microsoft names SkiaSharp, ImageSharp, Aspose.Drawing, and Microsoft.Maui.Graphics as alternatives. The cited guidance does not rank or compare them. Evaluate the target platforms, API fit, licensing, deployment requirements, and drawing features needed by your application before choosing one.
Quick Recap
A practical decision path
| Situation | Reasonable starting point |
|---|---|
| Existing Windows-only WinForms application | Keep System.Drawing/GDI+ where it fits the target runtime; paint through the lifecycle, dispose owned resources, and start with built-in buffering for ordinary flicker. |
| Custom control with visible flicker during painting | Try framework double buffering before introducing manual buffer management. |
| Animation or advanced buffer control requirement | Consider manual BufferedGraphics management when its additional control is justified. |
| Cross-platform drawing requirement | Assess the alternatives Microsoft names against your project’s platforms and constraints; the cited guidance does not establish a best choice. |
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




