我自己的使用位图的用户控件有两个问题:
- 如果通过 .NET 的“刷新”方法重绘,它会闪烁。
- 它的性能很差。
该控件由三个位图组成:
- 静态背景图像。
- 一个旋转的转子。
- 另一个取决于转子角度的图像。
所有使用的位图的分辨率均为 500x500 像素。控件的工作方式如下: https ://www.dropbox.com/s/t92gucestwdkx8z/StatorAndRotor.gif (这是一个 gif 动画)
用户控件应在每次获得新的转子角度时自行绘制。因此,它有一个公共属性“RotorAngle”,如下所示:
public double RotorAngle
{
get { return mRotorAngle; }
set
{
mRotorAngle = value;
Refresh();
}
}
Refresh
引发Paint
事件。事件OnPaint
处理程序如下所示:
private void StatorAndRotor2_Paint(object sender, PaintEventArgs e)
{
// Draw the three bitmaps using a rotation matrix to rotate the rotor bitmap.
Draw((float)mRotorAngle);
}
但是,当我使用此代码(在其他自己的用户控件中运行良好)时,如果控件通过SetStyle(ControlStyles.OptimizedDoubleBuffer, true)
. 如果我不将此标志设置为 true,则重绘时控件会闪烁。
在控制构造函数中我设置:
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);
首先,我认为它会闪烁,因为每次绘制控件时都会清除背景。因此,我设置SetStyle(ControlStyles.AllPaintingInWmPaint, true)
. 但这没有帮助。
那么,为什么会闪烁呢?其他控件在此设置下工作得很好。以及为什么不绘制如果SetStyle(ControlStyles.OptimizedDoubleBuffer, true)
。
Draw
我发现如果在更改属性后直接调用我的方法,控件不会闪烁RotorAngle
:
public float RotorAngle
{
get { return mRotorAngle; }
set
{
mRotorAngle = value;
Draw(mRotorAngle);
}
}
但这会导致性能非常差,尤其是在全屏模式下。不可能每 20 毫秒更新一次控件。你可以自己试试。我将在下面附上完整的 Visual Studio 2008 解决方案。
那么,为什么会出现如此糟糕的表现呢?每 20 毫秒更新一次其他(自己的)控件是没有问题的。真的只是因为位图吗?
我创建了一个简单的 Visual Studio 2008 解决方案来演示这两个问题: https ://www.dropbox.com/s/mckmgysjxm0o9e0/WinFormsControlsTest.zip (289,3 KB)
目录中有一个可执行文件bin\Debug
。
谢谢你的帮助。