I have two problems with my own user control that uses bitmaps:
- It flickers if it is redrawn using the .NET Refresh method.
- It has poor performance.
The control consists of three raster images:
- Static background image.
- Rotating rotor.
- Another image depending on the angle of the rotor.
All used raster images have a resolution of 500x500 pixels. Management works as follows: https://www.dropbox.com/s/t92gucestwdkx8z/StatorAndRotor.gif (this is a gif animation)
The user control must draw each time it receives a new rotor angle. Therefore, it has the public property "RotorAngle", which is as follows:
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) {
But when I use this code that works well in my other custom user controls - the user control is not drawn at all if the control is double-buffered via SetStyle(ControlStyles.OptimizedDoubleBuffer, true)
. If I do not set this flag to true, the control flickers when redrawing.
In the 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);
Firstly, I thought it was flickering because the background is cleared every time the control is drawn. Therefore, I set SetStyle(ControlStyles.AllPaintingInWmPaint, true)
. But it did not help.
So why does it flicker? Other controls work very well with this setting. And why is this contradiction not drawn if SetStyle(ControlStyles.OptimizedDoubleBuffer, true)
.
I found out that the control does not flicker if I call my Draw
method immediately after changing the RotorAngle
property:
public float RotorAngle { get { return mRotorAngle; } set { mRotorAngle = value; Draw(mRotorAngle); } }
But this leads to very poor performance, especially in full screen mode. Unable to update control every 20 milliseconds. You can try it yourself. Below I will attach the complete solution to Visual Studio 2008.
So why is this such a bad job? There is no problem updating other (native) controls every 20 milliseconds. Is it really just because of bitmaps?
I created a simple visual solution for Visual Studio 2008 to demonstrate two problems: https://www.dropbox.com/s/mckmgysjxm0o9e0/WinFormsControlsTest.zip (289.3 KB)
The bin\Debug
directory has an executable file.
Thanks for your help.