使用Winforms绘图 [英] Drawing with Winforms

查看:102
本文介绍了使用Winforms绘图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想对WinForm Graphics有所了解,所以我正在将我的小型2D编辑器从XNA重写为仅WinForm Graphics.

I want to get myself a bit of WinForm Graphics knowledge, so I'm rewriting my small 2D editor from XNA to WinForm Graphics-only.

现在,我为自己创建了一个用于图块集的新UserControl,但是正如我所看到的,Paint方法仅在控件初始化时调用.由于我想永久重画控件(或至少通过MouseOver事件以节省一些性能),因此我听说Invalidate()方法让控件重画自身,但这是方式表现不佳.

Now, I made myself a new UserControl for the tileset, but as I've seen, the Paint method is only called at the initialization of the control. Since I want to permanently repaint my control (or at least via MouseOver event to save a bit of performance), I heard the Invalidate() method gets the Control to repaint itself, but that is way too unperformant.

有没有什么方法可以让我的UserControl在没有这些性能问题的情况下通过代码绘制自身?

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

推荐答案

>方法不是 ,仅在控件初始化时调用.每次需要重新绘制控件时都会调用它.当然,这是在第一次创建控件时发生的.当您的应用程序最小化然后还原时,当另一个窗口移到您的应用程序上而其内容模糊然后被删除时,也会发生这种情况,依此类推.当您使用Invalidate方法或等效方法使控件的工作区无效时,也会发生这种情况.这是在Windows开发的早期进行的,目的是进行性能优化-无需重新绘制未更改的内容!

The Paint method is not only called at the initialization of the control. It is called every time that the control needs to be repainted. This, of course, happens when the control is first created. It also happens when your application is minimized then restored, when another window is moved over your app that obscures its contents and then removed, and so on. It also happens when you invalidate the control's client area using the Invalidate method or equivalents. This was done early in the development of Windows as a performance optimization—there's no need to repaint something that hasn't changed!

如果要强制重绘控件,则应调用 Invalidate方法,并指定要重新粉刷的客户区域的特定区域.

If you want to force the control to be repainted, you should call the Invalidate method and specify a particular region of the client area to be repainted.

我不知道您对表现不佳"的意思. Invalidate方法不可能很慢.它所做的全部是设置一个标志,该标志告诉Windows您需要在空闲时重新绘制控件(不处理任何其他消息).

I have no idea what you mean about "that is way too unperformant". It's impossible for the Invalidate method to be slow. All it does is set a flag that tells Windows your control needs to be redrawn whenever it is idle (not processing any other messages).

如果您想强制Windows立即重新绘制控件(emem)(而不等待空闲);早期Windows中内置的另一种性能优化,请调用

If you want to force Windows to repaint your control immediately (without waiting for it to be idle; another performance optimization built into Windows from the early days), call the Update method, which forces an immediate redraw of all invalidated regions.

唯一可能变慢的方法是 drawing 代码在Paint事件处理程序方法内部变慢.很明显,我无法告诉您如何在不先看到代码的情况下优化该代码.

The only way it could be slow is if your drawing code is slow inside of the Paint event handler method. And obviously I can't tell you how to optimize that code without seeing it first.

有没有让我的UserControl通过代码绘制自身而又没有这些性能问题的方法?

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

Paint事件正是控件应如何绘制自身以及在何处绘制自身.这就是为什么它在那里.

The Paint event is precisely how and where controls should paint themselves. That's why it's there.

如果您在Paint事件中不要绘制,则您绘制的所有内容都会在下次重新绘制控件时被擦除(如前所述,响应于任何数量的预期和意外事件).

If you don't paint in the Paint event, anything that you paint will be erased the next time that the control is repainted (which, as mentioned earlier, can happen in response to any number of expected and unexpected occurrences).

尽管如此,有时还是可以将临时对象绘制到控件的工作区中(例如,响应MouseDown事件而显示拖动矩形).在这种情况下,您可以随时获取Graphics类的实例(通常将其作为参数传递给Paint事件处理程序方法,并在其上调用方法进行绘制).您可以通过调用 CreateGraphics方法在您的控件上,它返回一个Graphics对象.然后,您可以像在Paint事件处理程序方法内部一样,将获取的对象吸引到Graphics对象中.

Sometimes, though, it makes sense to paint temporary objects into the control's client area (such as showing a drag rectangle in response to a MouseDown event). In that case, you can obtain an instance of the Graphics class (which is typically passed as an argument to your Paint event handler method, and on which you call methods to do your drawing) at any time. You do this by calling the CreateGraphics method on your control, which returns a Graphics object. You then draw into/onto the Graphics object obtained just as you would inside of the Paint event handler method.

很明显,这不可能/不会比Paint事件处理程序方法中的绘图代码(如果实际上是罪魁祸首)要快,但是它将导致屏幕更新 ,而不是每当控件处于空闲状态且不处理任何其他消息时.

Obviously this can't/won't be any faster than the drawing code inside of the Paint event handler method (if that is in fact the culprit), but it will cause the screen to be updated immediately rather than whenever the control is idle and not processing any other messages.

我将再次重申,此方法仅用于 ,以提供即时和临时反馈,因为下次绘制控件时,您绘制的所有内容都会被删除.重画.发生这种情况时,会引发Paint事件,并且该方法处理程序中的代码将运行,而对于在其他一些一次性情况下绘制的内容一无所知.这就是为什么所有事情都应该在Paint事件处理程序方法内部发生的原因,并且当某些其他事件需要重绘时,您应该调用Invalidate(也许不是,通常不是Update).

I'll reiterate again that this approach should be used only to provide immediately and temporary feedback, as everything you draw will be erased the next time that the control is redrawn. When that happens, the Paint event is raised, and your code inside that method handler runs, which doesn't know anything about what you drew on some other one-off occasion. That's why everything should happen inside of the Paint event handler method, and you should call Invalidate (and perhaps, though not usually, Update) when some other event makes it necessary to repaint.

这篇关于使用Winforms绘图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆