【问题标题】:How to draw rectangles consecutively in sth like a loop in Winform如何像Winform中的循环一样连续绘制矩形
【发布时间】:2014-10-24 13:18:09
【问题描述】:

我需要在 Winform 中绘制矩形,如下图:

我也应该更清楚。我想实现这种情况:假设有一个类似“ABCDEFG”的文本当用户单击 B 字母时,我想为该字母和连续的 3 个字母添加一个带颜色(突出显示)的背景矩形(在这种情况下,我想突出显示 BCD)。

在我尝试过的方法中:

for (int i = 0; i < 5; i++)
{
    letterArea = new Rectangle(rectStartX, rectStartY, (int)Math.Ceiling(charSize.Width), (int)Math.Ceiling(charSize.Height));
    rectStartX += (int)Math.Ceiling(charSize.Width);
}

我在这个方法的最后调用 Invalidate()。在 OnPaintBackGround 我有这些行:

Rectangle rectContent = vsr.GetBackgroundContentRectangle(e.Graphics, this.ClientRectangle);
e.Graphics.FillRectangle(new SolidBrush(Color.Red), letterArea);

其中 letterArea 是一个类字段。我在另一个问题中读到,在循环中调用 Invalidate() 并不能保证调用 OnPaintBackground。我对计算坐标不感兴趣,相反,我对必须绘制矩形的方法以及在哪里调用 Invalidate() 以及什么是有效的解决方案感兴趣? 提前谢谢。

【问题讨论】:

  • Invalidate 将绘制消息发送到窗口。 Paint 分别发送一个 erasebackground。在循环中发送一个或 1000 个无效不会改变任何东西。最后只会发送一条绘制消息。在 paint 中绘制是常见的做法
  • 在循环中调用 Invalidate() 并不能保证调用 OnPaintBackground。 是的。可能不会立即,也不会比必要的更频繁,但您可以放心地依靠控件来绘制。
  • 在您的方法中,您创建了多个 Rectangle,但您没有对它们做任何事情?如果您将它们添加到类级别 List 您的绘画事件可以使用它来填充它们中的每一个..
  • 这会有效还是解决问题的正确方法?还是只是一个解决方案?
  • 这样就好了。甚至没有理由考虑这个级别的效率..这是最好的方法吗?不知道,因为坦率地说,你没有很好地描述这个问题。你给我们展示了一张漂亮的图片,但它没有任何字母,那么它是什么关系??

标签: c# winforms user-interface drawing rectangles


【解决方案1】:

您应该使用OnPaint 方法而不是OnPaintBackground 来绘制矩形。

另请注意,调用Invalidate() 不会强制同步绘制。要强制同步绘制,请在调用Invalidate() 后调用Update() 或使用Refresh(),其作用与Invalidate + Update 相同(但也会影响子控件)。参考MSDN

【讨论】:

  • 安迪我更新了我的问题以更清楚。当我想突出某些字母的背景时,在 OnPaint 中绘图是否仍然有效?谢谢。
  • 在表单代码中,您总是想要在OnPaint() 中绘图。您需要维护描述您的视觉外观的数据结构(例如,矩形列表、文本突出显示等),当任何数据更改时调用Invalidate(),然后在调用OnPaint() 时绘制正确的视觉外观.另请注意,虽然 .NET 提供了同步绘制 API,但使用它几乎从来都不是正确的选择。等待 WM_PAINT 消息(这是导致 OnPaint() 被调用的原因)然后重绘是正常且正确的方法。
猜你喜欢
  • 1970-01-01
  • 2016-08-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-11-09
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多