Ben*_*ikt 6 c# performance user-controls flicker winforms
我有一个使用位图的自己的用户控件有两个问题:
该控件由三个位图组成:
所有使用的位图都具有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 Visual Studio 2008解决方案来演示这两个问题: https://www.dropbox.com/s/mckmgysjxm0o9e0/WinFormsControlsTest.zip(289,3 KB)
目录中有一个可执行文件bin\Debug.
谢谢你的帮助.
首先,根据 LarsTech 的回答,您应该Graphics使用PaintEventArgs. 通过在处理程序CreateGraphics()内部调用Paint,您将无法OptimizedDoubleBuffer正常工作。
其次,在 SetStyle 块中添加:
SetStyle( ControlStyles.Opaque, true );
...以防止基类 Control 在调用 Paint 处理程序之前填充背景颜色。
我在你的示例项目中对此进行了测试,它似乎消除了闪烁。
| 归档时间: | 
 | 
| 查看次数: | 2823 次 | 
| 最近记录: |