Vb.net 在表格上无滞后地绘制图形?

Vb.net 在表格上无滞后地绘制图形?,vb.net,winforms,gdi,Vb.net,Winforms,Gdi,我的方法的问题是,在调整表单大小时,图像、文本或线条绘制可能会滞后0.2秒。所以,若你们需要一个位于右下角的图像,那个么在调整大小后需要0.2秒的时间。此外,如果你做了大量的调整,它开始滞后到1-2FPS,而窗体在大屏幕上展开。示例代码如下所示(VB.NET): 有什么方法可以使它更平滑吗?调整窗口大小总是需要在新位置重新绘制图像。但是,您可以尝试一些方法来提高重画的效率 只会使图像的新旧位置无效,而不是整个形式无效。这意味着您不必绘制不变的窗口部分 将图像从旧位置复制到新位置。在这里,您必须小

我的方法的问题是,在调整表单大小时,图像、文本或线条绘制可能会滞后0.2秒。所以,若你们需要一个位于右下角的图像,那个么在调整大小后需要0.2秒的时间。此外,如果你做了大量的调整,它开始滞后到1-2FPS,而窗体在大屏幕上展开。示例代码如下所示(VB.NET):


有什么方法可以使它更平滑吗?

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

  • 只会使图像的新旧位置无效,而不是整个形式无效。这意味着您不必绘制不变的窗口部分
  • 将图像从旧位置复制到新位置。在这里,您必须小心使窗口的正确部分无效,特别是当窗口变小,新旧图像区域重叠时
  • 为图像创建单独的控件,并将控件移动到正确的位置。表单和控件将自动使正确的区域无效

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

  • 只会使图像的新旧位置无效,而不是整个形式无效。这意味着您不必绘制不变的窗口部分
  • 将图像从旧位置复制到新位置。在这里,您必须小心使窗口的正确部分无效,特别是当窗口变小,新旧图像区域重叠时
  • 为图像创建单独的控件,并将控件移动到正确的位置。表单和控件将自动使正确的区域无效
  • Windows窗体提供了一个双重缓冲区来缓冲屏幕。这会为您进行大量设置

    此外,双缓冲消除了清除屏幕的需要,因此重写
    OnPaintBackground
    并在不调用基类的情况下返回将阻止大量无论如何都看不到的工作

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

    Windows窗体提供了一个双缓冲屏幕。这会为您进行大量设置

    此外,双缓冲消除了清除屏幕的需要,因此重写
    OnPaintBackground
    并在不调用基类的情况下返回将阻止大量无论如何都看不到的工作



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

    我没有看到您发布的代码有任何明显的延迟。@JohnKoerner:奇怪的是,我在运行相同Windows 7的速度慢5倍的机器上进行了尝试,但也没有发现明显的延迟。所以现在我的i7给了我很多问题。如果发现任何模式,我将进行更多测试并更新问题。尝试将
    Invalidate()
    替换为
    Refresh()
    @ja72:刚刚尝试过,在当前上下文中,Invalidate=Refresh。我没有看到您发布的代码有任何明显的延迟。@JohnKoerner:奇怪的是,我在运行相同Windows 7的速度慢5倍的机器上进行了尝试,也没有发现明显的延迟。所以现在我的i7给了我很多问题。如果发现任何模式,我将进行更多测试并更新问题。尝试将
    Invalidate()
    替换为
    Refresh()
    @ja72:刚刚尝试过,在当前上下文中,Invalidate=Refresh。此外,paintEventArgs将有一个“invalid”rect-标识需要重新绘制的实际位。这通常可用于进一步限制所需的渲染。请详细说明如何使希望稍后重新绘制的区域无效(对于上述场景)?我试着使用和Resize事件相同的矩形来绘制,但似乎在那个时候一切都已经发生了,所以我需要在Resize之前完成。试图覆盖并将其放在Mybase之前。绘制,但仍然是一样的东西。调整大小时,我看到图像的痕迹。痕迹的大小取决于我调整大小的速度。@Neolisk我认为您可能必须保存以前绘制的区域,以便使其无效,然后将其更新到要绘制图像的位置并使其无效。此外,paintEventArgs将有一个“无效”矩形,标识需要重新绘制的实际位。这通常可用于进一步限制所需的渲染。请详细说明如何使希望稍后重新绘制的区域无效(对于上述场景)?我试着使用和Resize事件相同的矩形来绘制,但似乎在那个时候一切都已经发生了,所以我需要在Resize之前完成。试图覆盖并将其放在Mybase之前。绘制,但仍然是一样的东西。调整大小时,我看到图像的痕迹。痕迹的大小取决于我调整大小的速度。@Neolisk我认为您可能必须保存以前绘制的区域,以便使其无效,然后将其更新到要绘制图像的位置并使其无效。这与使用Form.DoubleBuffered相同吗?是的,它们都是设置相同内容的方法。您可以在表单初始化代码中显式调用该方法或设置样式。我尝试了双缓冲——但没有解决问题。事实上,每次有人提出这一建议,都无济于事这和使用Form.DoubleBuffered一样吗?是的,它们都是设置相同内容的方法。您可以在表单初始化代码中显式调用该方法或设置样式。我尝试了双缓冲——但没有解决问题。事实上,每次有人提出这一建议,都无济于事
    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