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.
if (SystemInformation.TerminalServerSession) ...
– Bridge