.net - 使用 Winform 绘图

标签 .net windows winforms drawing paint

我想获得一些 WinForm Graphics 知识,因此我正在将我的小型 2D 编辑器从 XNA 重写为仅限 WinForm Graphics。

现在,我为图 block 集创建了一个新的 UserControl,但正如我所见,Paint 方法仅在控件初始化时调用。由于我想永久地重新绘制我的控件(或者至少通过 MouseOver 事件来节省一些性能),我听说 Invalidate() 方法让 Control 重新绘制自身,但这方式性能太差。

有什么方法可以让我的 UserControl 通过代码进行 self 绘制,而不会出现这些性能问题?

最佳答案

Paint 方法不仅仅仅在控件初始化时调用。每次需要重新绘制控件时都会调用它。当然,这是在首次创建控件时发生的。当您的应用程序最小化然后恢复时,当另一个窗口移动到您的应用程序上并遮盖其内容然后被删除时,也会发生这种情况。当您使用 Invalidate 方法或等效方法使控件的工作区无效时,也会发生这种情况。这是在 Windows 开发早期作为性能优化而完成的 - 无需重新绘制未更改的内容!

如果你想强制重新绘制控件,你应该调用 Invalidate method并指定要重新绘制的客户区的特定区域。

我不知道你所说的“那方式性能太差”是什么意思。 Invalidate 方法不可能慢。它所做的只是设置一个标志,告诉 Windows 您的控件在空闲时需要重绘(不处理任何其他消息)。

如果您想强制 Windows 立即重新绘制控件(无需等待其空闲;Windows 早期内置的另一项性能优化),请调用 Update method ,这会强制立即重绘所有无效区域。

唯一可能变慢的原因是您的绘图代码在Paint事件处理程序方法内运行缓慢。显然,如果没有先看到代码,我就无法告诉您如何优化该代码。


Is there anyway to let my UserControl paint itself via code, without having these performance-issues?

Paint 事件正是控件应如何以及在何处进行 self 绘制。这就是它存在的原因。

如果您Paint事件中进行绘制,则下次重新绘制控件时您绘制的任何内容都将被删除(如前所述,可以响应任意数量的预期和意外事件而发生)。

但有时,将临时对象绘制到控件的工作区中是有意义的(例如显示一个拖动矩形以响应 MouseDown 事件)。在这种情况下,您可以获得 Graphics 类的实例(通常作为参数传递给 Paint 事件处理程序方法,并在其上调用方法来执行以下操作)您的绘图)随时。您可以通过调用 CreateGraphics method 来完成此操作在您的控件上,它返回一个 Graphics 对象。然后,您可以在获得的 Graphics 对象中进行绘制,就像在 Paint 事件处理程序方法中一样。

显然,这不能/不会比 Paint 事件处理程序方法内的绘图代码快(如果这实际上是罪魁祸首),但它会导致屏幕立即更新,而不是在控件空闲且不处理任何其他消息时更新。

我再次重申,这种方法应该用于提供即时和临时反馈,因为下次控件被删除时,您绘制的所有内容都将被删除重新绘制。发生这种情况时,将引发 Paint 事件,并且该方法处理程序中的代码将运行,该代码对您在其他一次性场合绘制的内容一无所知。这就是为什么一切都应该发生在 Paint 事件处理程序方法内,并且您应该在以下情况下调用 Invalidate (也许,尽管不常见,Update):其他一些事件使得有必要重新绘制。

关于.net - 使用 Winform 绘图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8996409/

相关文章:

windows - 如何使用 DvbSiparser.h 在 vc++ 中解析 mpeg2 TS?

winforms - 从 Backgroundworker DoWork 访问窗口控制

c# - 将BackgroundWorker转换为具有模态显示的Task.Run

.net - RIA 服务服务器端异常处理

c# - 如何在 C# 中截断文件?

Python 正则表达式在 Python 2 中有效,但在 Python 3 中无效

c++ - 我应该使用什么信号来终止/终止 Windows 上的应用程序?

c# - 在 C# 或 VB.NET 中使用 'System.Activities.Statements.StateMachine' 类的示例

c# - 对于实现接口(interface)的类型,你怎么能要求一个没有参数的构造函数呢?

winforms - 如何处理 CefSharp 中的弹出链接