【问题标题】:Control.Invalidate() or Control.Invalidate(Rectangle)Control.Invalidate() 或 Control.Invalidate(Rectangle)
【发布时间】:2020-08-07 17:47:37
【问题描述】:

我应该使用Control.Invalidate() 还是最好使用Control.Invalidate(Rectangle)? MSDN 对这些方法的信息有点缺乏。

在这两种情况下,都会调用相同的OnPaint 方法并执行相同的代码行。那么这里有什么区别,除了我必须计算矩形结构来告诉windows应该重绘哪个区域?

我觉得我一直使用Control.Invalidate() 会更安全,但同时我觉得我编写了糟糕的代码并失去了性能。

【问题讨论】:

  • 如果你想使整个事情无效,只使用 Invalidate()。如果只想使控件的一部分无效,请使用 Rectangle 方法。这只是一种优化技术。单独使用 Invalidate() 应该没问题。大多数情况下,这些东西都是双缓冲的,据我所知,整个东西都会被重新绘制。我认为InvalidateRect 的东西是 CPU 和 GPU 能力非常有限的时期的产物。现在真的不是这样了,尤其是 GDI。
  • Invalidate(Rectangle) 仅在您可以在 Paint 事件中重绘部分区域时才有意义。如果总是重绘整个区域,那就没有意义了。
  • @AlexanderPetrov,这不是真的。您总是在Paint 事件处理程序中完成所有绘图。这与Invalidate 完全无关。您每次都进行所有绘图,然后只有落入无效区域的绘图部分实际上被绘制到屏幕上。是绘画部分,而不是绘画部分,这很慢。

标签: c# .net vb.net


【解决方案1】:

您应该始终使最小的区域无效,因此您应该传递RectangleRegion,除非整个控制区域已经或可能已经改变。这样做的原因是,将像素实际绘制到碎石上是整个操作中最慢的部分,并且无效区域内的每个像素都将被重新绘制。也就是说,像素越少,重绘的速度就越快。

您可能并不总是能够看到差异,但尤其是如果您经常重新绘制,可能会出现明显的性能差异。通常,执行稍微复杂的计算来确定最小的RectangleRegion 比重新绘制额外的像素要快得多。

【讨论】:

  • 也许我低估了绘图方法的成本。您将如何处理客户提供的通过更改在指定区域(Graphics.Clip 内指定)之外绘制的方法?不能保证我之前传入的区域和他之前画的一样。
  • 我不确定你的意思。如果一个方法正在绘制,那么可能Paint 事件已经引发,所以Invalidate 已经被调用。这意味着在调用Invalidate 时应该已经计算并指定了可能已更改的区域。您不应该在现有问题的答案的 cmets 中提出新问题。如果您有新问题,请发布一个包含与该问题相关的所有信息的新问题。
  • @keco 您可以让客户端传递绘制到的图像部分的坐标。然后,您将它们用作Control.Invalidate() 的参数。
猜你喜欢
  • 1970-01-01
  • 2016-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多