gpt4 book ai didi

c# - 自己的WinForms控件闪烁且性能不佳

转载 作者:太空狗 更新时间:2023-10-29 21:13:50 30 4
gpt4 key购买 nike

我有两个使用位图的用户控件的问题:

  1. 如果通过 .NET 的“刷新”方法重新绘制,它会闪烁。
  2. 性能不佳。

控件由三个位图组成:

  • 一张静态背景图片。
  • 一个旋转的转子。
  • 另一个图像取决于转子角度。

所有使用的位图都具有 500x500 像素的分辨率。控件的工作原理如下: https://www.dropbox.com/s/t92gucestwdkx8z/StatorAndRotor.gif (这是一个gif动画)

用户控件应在每次获得新的转子角度时自行绘制。因此,它有一个公共(public)属性“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) 为什么不绘制控件。

我发现如果我在更改属性 RotorAngle 后直接调用我的 Draw 方法,控件不会闪烁:

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 中有一个可执行文件。

感谢您的帮助。

最佳答案

首先,根据 LarsTech 的回答,您应该使用 PaintEventArgs 中提供的 Graphics 上下文。通过在 Paint 处理程序中调用 CreateGraphics(),可以防止 OptimizedDoubleBuffer 正常工作。

其次,在您的 SetStyle block 中,添加:

SetStyle( ControlStyles.Opaque, true );

... 以防止基类 Control 在调用您的 Paint 处理程序之前填充背景颜色。

我在您的示例项目中对此进行了测试,它似乎消除了闪烁。

关于c# - 自己的WinForms控件闪烁且性能不佳,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10585756/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com