Own WinForms Control Flickers and Has Bad Performance

c#, flicker, performance, user-controls, winforms

Solution

First, per LarsTech's answer, you should use the `Graphics` context provided in the `PaintEventArgs`. By calling `CreateGraphics()` inside the `Paint` handler, you prevent `OptimizedDoubleBuffer` from working correctly.

Second, in your SetStyle block, add:

SetStyle( ControlStyles.Opaque, true );

... to prevent the base class Control from filling in the background color before calling your Paint handler.

I tested this in your example project, it seemed to eliminate the flickering.

Problem

I have two problems with an own user control which uses bitmaps: - It flickers if it's redrawn via .NET's 'Refresh' method. - It has a bad performance. The control consists of three bitmaps: - A static background image. - A rotating rotor. - Another image depending on rotor angle. All used bitmaps have a resolution of 500x500 pixels. The control works like this: https://www.dropbox.com/s/t92gucestwdkx8z/StatorAndRotor.gif (it's a gif animation) The user control should draw itself everytime it gets a new rotor angle. Therefore, it has a public property 'RotorAngle' which looks like this: ``` public double RotorAngle { get { return mRotorAngle; } set { mRotorAngle = value; Refresh(); } } ``` `Refresh` raises the `Paint` event. The `OnPaint` event handler looks like this: ``` private void StatorAndRotor2_Paint(object sender, PaintEventArgs e) { // Draw the three bitmaps using a rotation matrix to rotate the rotor bitmap. Draw((float)mRotorAngle); } ``` But when I use this code - which works well in other own user controls - the user control is not drawn at all if control is double buffered via `SetStyle(ControlStyles.OptimizedDoubleBuffer, true)`. If I don't set this flag to true, the control flickers when being redrawn. In control constructor I set: ``` SetStyle(ControlStyles.AllPaintingInWmPaint, true); SetStyle(ControlStyles.ContainerControl, false); // User control is not drawn if "OptimizedDoubleBuffer" is true. // SetStyle(ControlStyles.OptimizedDoubleBuffer, true); SetStyle(ControlStyles.ResizeRedraw, true); SetStyle(ControlStyles.SupportsTransparentBackColor, true); ``` First, I thought it flickers because the background is cleared everytime the control is drawn. Therefore, I set `SetStyle(ControlStyles.AllPaintingInWmPaint, true)`. But it didn't help. So, why does it flicker? Other controls work very well with this setup. And why is the controly not drawn if `SetStyle(ControlStyles.OptimizedDoubleBuffer, true)`. I found out that the control does not flicker if I invoke my `Draw` method directly after changing the property `RotorAngle`: ``` public float RotorAngle { get { return mRotorAngle; } set { mRotorAngle = value; Draw(mRotorAngle); } } ``` But this results in a very bad performance, especially in full screen mode. It's not possible to update the control every 20 milliseconds. You can try it yourself. I will attach the complete Visual Studio 2008 solution below. So, why it is such a bad performance? It's no problem to update other (own) controls every 20 milliseconds. Is it really just due to the bitmaps? I created a simple visual Visual Studio 2008 solution to demonstrate the two problems: https://www.dropbox.com/s/mckmgysjxm0o9e0/WinFormsControlsTest.zip (289,3 KB) There is an executable in directory `bin\Debug`. Thanks for your help.

Original source

Related problems