【问题标题】:Draw graphics on a form without lags?在没有滞后的表单上绘制图形?
【发布时间】:2012-10-01 09:12:10
【问题描述】:

我的方法的问题是,在调整表单大小时,图像、文本或绘制的线条可能会滞后 0.2 秒。因此,如果您需要右下角的图像,则在调整大小后需要 0.2 秒才能到位。此外,如果您进行大量调整大小,它开始滞后到 1-2FPS,而表单在大屏幕上展开。示例代码如下所示(VB.NET):

Public Class Form1
  Protected Overrides Sub OnPaint(e As System.Windows.Forms.PaintEventArgs)
    MyBase.OnPaint(e)
    Dim icon As Icon = SystemIcons.Exclamation
    Dim imageWidth As Integer = icon.Width
    Dim imageHeight As Integer = icon.Height
    e.Graphics.DrawIcon(icon, Me.ClientRectangle.Right - imageWidth,
                              Me.ClientRectangle.Bottom - imageHeight)
  End Sub
  Private Sub Form1_Resize(sender As Object, e As System.EventArgs) Handles Me.Resize
    Me.Invalidate()
  End Sub
End Class

有什么办法可以让它更流畅吗?

【问题讨论】:

  • 我没有看到您发布的代码有任何明显的延迟。
  • @JohnKoerner:奇怪的是,我在运行相同 Windows 7 的慢 5 倍的机器上进行了尝试,但也没有发现明显的延迟。所以目前只有我的 i7 给我带来了问题。如果我发现任何模式,我会做更多的测试并更新问题。
  • 尝试用Refresh()替换Invalidate()
  • @ja72: 刚试过,在当前上下文中似乎 Invalidate = Refresh。

标签: vb.net winforms gdi


【解决方案1】:

Windows 窗体提供了一个style setting 来双重缓冲屏幕。这为您做了很多设置。

此外,双缓冲消除了清除屏幕的需要,因此覆盖OnPaintBackground 并返回而不调用基类将阻止许多无论如何都不会看到的工作。

有关 GDI+/winforms 双缓冲的一些最佳示例,请查看我的animationexamples

【讨论】:

  • 和使用Form.DoubleBuffered一样吗?
  • 是的,它们都是设置相同内容的方式。您可以在表单初始化代码中显式调用方法或设置样式。
  • 我试过DoubleBuffered - 它没有解决问题。事实上,每次有人提出这个建议时,它都无济于事。 :)
【解决方案2】:

调整窗口大小总是需要在新位置重新绘制图像。但是,您可以尝试一些可能会或可能不会提高重绘效率的方法。

  1. 仅使图像的新旧位置无效,而不是整个表格。这意味着您不必绘制不会更改的窗口部分。
  2. 将图像从旧位置复制到新位置。在此您必须小心使窗口的右侧部分无效,尤其是当窗口变小并且新旧图像区域重叠时。
  3. 为图像创建一个单独的控件,并将该控件移动到正确的位置。然后,表单和控件将自动使正确的区域无效。

【讨论】:

  • 此外,paintEventArgs 将有一个“无效”矩形 - 标识需要重绘的实际位。这通常可用于进一步限制所需的渲染。
  • 您能否详细说明如何使您希望稍后重新绘制的区域无效(对于上述情况)?我尝试使用与 Resize 事件一起绘制的相同矩形,但似乎一切都已经发生在那个时候,所以我需要在 Resize 之前这样做。试图覆盖并将其放在 Mybase.Paint 之前,但仍然相同。调整大小时,我看到了图像的痕迹。痕迹的大小取决于我调整大小的速度。
  • @Neolisk 我认为您可能必须保存先前绘制的区域,以便您可以使其无效,然后将其更新到您打算绘制图像的位置并使其无效。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-30
  • 1970-01-01
  • 2014-01-14
相关资源
最近更新 更多