[英]Do I have to keep creating a Graphics object
I am an old delphi programmer, I am used to creating objects and using them entire time for efficient memory usage. 我是一个老的delphi程序员,我习惯于创建对象并将它们全部用于有效的内存使用。 But in c# (maybe all the tutorials I've ever seen), you are creating stuffs with
new
every time (thanks to garbage collector!!, let me do the coding).. 但是在c#(也许是我见过的所有教程)中,你每次都在用
new
东西创建东西(感谢垃圾收集器!!,让我做编码)..
Anyway, I am trying to create a designing software which has lots of drawing. 无论如何,我正在尝试创建一个有很多绘图的设计软件。 My question is: do I have to create a graphics object, or use the
protected override void OnPaint(PaintEventArgs e)
e.Graphics every painting event.. because when I create a graphic object and then resize the control that I draw on, the graphic object that I created, has that clipping problem and only draws old rectangle region.. 我的问题是:我是否必须创建一个图形对象,或者使用
protected override void OnPaint(PaintEventArgs e)
e.Graphics每个绘制事件..因为当我创建一个图形对象然后调整我绘制的控件时,我创建的图形对象,有剪切问题,只绘制旧的矩形区域..
thanks 谢谢
Caching objects makes sense when the object is expensive to create, cheap to store and relatively simple to keep updated. 当对象创建昂贵,存储便宜并且保持更新相对简单时,缓存对象是有意义的。 A Graphics object is unique in that none of these conditions are true:
在没有这些条件都为真Graphics对象是独一无二的:
Caching a Graphics object is a bug. 缓存Graphics对象是一个错误。
If you want to draw on the surface always use the Graphics
object from the Paint
event! 如果要在曲面上绘图,请始终使用
Paint
事件中的Graphics
对象!
If you want to draw into a Bitmap
you create a Graphics
object and use it as long as you want. 如果要绘制到
Bitmap
可以创建Graphics
对象并根据需要使用它。
For the Paint
event to work you need to collect all drawing in a List
of graphic actions; 要使
Paint
事件起作用,您需要收集图形操作List
的所有图形; so you will want to make a nice class to store all parameters needed. 所以你会想要一个很好的类来存储所需的所有参数。
In your case you may want to consider a mixed approach: Old graphic actions draw into a bitmap, which is the eg BackgroundImage
or Image
of your control 在您的情况下,您可能需要考虑混合方法:旧图形操作绘制到位图,例如
BackgroundImage
或控件的Image
Current/ongoing drawing are done on the surface. 当前/正在进行的绘图在表面上完成。 This amounts to using the bitmap as a cache , so you don't have to redraw lots of actions on every little change etc
这相当于使用位图作为缓存 ,因此您不必在每次微小的更改等上重绘大量操作
This is closely related to your undo/redo
implementation. 这与您的
undo/redo
实现密切相关。 You could set a limit and draw those before into a Btimap and those after onto the surface.. 您可以设置一个限制,然后将它们绘制到Btimap中,然后绘制到表面之后。
PS: You also should rethink your GC
attitude. PS:你也应该重新思考你的
GC
态度。 It is simple, efficient and a blessing to have around. 它简单,高效,是一种祝福。 (And, yes, I have done my share of TP&Delphi, way back when they were affordable..) - Yes, we do the coding, but
GC
is not about coding but about house keeping. (而且,是的,我已经完成了TP&Delphi的份额,当它们价格合理的时候就可以了。) - 是的,我们进行编码,但
GC
并不是关于编码而是关于管家。 Boring at best.. (And you can always design to avoid it, but not with a Graphics
object in a windows system.) 最好无聊..(你可以设计避免它,但不能在Windows系统中使用
Graphics
对象。)
A general rule for every class that implements IDisposable is to Dispose() it, as soon as possible. 实现IDisposable的每个类的一般规则是尽快Dispose()它。 Make sure you know about the
using(...){}
statement. 确保您了解
using(...){}
语句。
For drawing in WinForms (GDI+) the best practice is indeed to use the Graphics object from PaintEventArgs. 对于WinForms(GDI +)中的绘图,最佳实践确实是使用PaintEventArgs中的Graphics对象。 And because you didn't create that one, do not Dispose() it.
因为你没有创建一个,请不要将其()它。 Don't stash it either.
也不要藏匿它。
I have to completely disagree with other more experienced members here who say it's no big deal or in fact better to recreate the Graphics object over and over. 我必须完全不同意其他更有经验的成员,他们说这不是什么大不了的事,或者实际上更好地重复一遍又一遍地重新创建Graphics对象。
The HDC is a pointer to a HDC__ struct, which is a struct with one member, "int unused". HDC是指向HDC__结构的指针,该结构是一个具有一个成员“int unused”的结构。 It's an absolute waste and stupidity to create another instance/object every time drawing needs to be done.
每次需要绘制时,创建另一个实例/对象绝对浪费和愚蠢。 The HDC is NOT large, it's either 4 or 8 bytes, and the struct it points to is in nearly all cases 4 bytes.
HDC并不大,它是4或8个字节,它指向的结构几乎在所有情况下都是4个字节。 Furthermore, on the point that one person made, it doesn't help that the graphics object be made with the "static" keyword at the beginning of the WndProc() before the switch, because the only way to give the Graphics object a device context or handle to paint on is by calling its constructor, so "static" does nothing to save you from creating it over and over again.
此外,就一个人所做的那样,在切换之前的WndProc()开头用“static”关键字创建图形对象没有帮助,因为给Graphics对象一个设备的唯一方法上下文或绘制的句柄是通过调用它的构造函数,因此“静态”不会阻止你反复创建它。
On top of that Microsoft recommends that you create a HDC pointer and assign it to the same value PAINTSTRUCT already has, every, single WM_PAINT message it sends. 最重要的是,Microsoft建议您创建一个HDC指针并将其分配给PAINTSTRUCT已经拥有的相同值,它发送的每个单个WM_PAINT消息。
I'm sorry but the WinAPI in my opinion is very bad. 对不起,我认为WinAPI非常糟糕。 Just as an example, I spent all day researching how to make a child WS_EX_LAYERED window, to find out that in order to enable Win 8 features one has to add code in XML with the OS's ID number to the manifest.
作为一个例子,我花了一整天时间研究如何创建一个子WS_EX_LAYERED窗口,以发现为了启用Win 8功能,必须将带有操作系统ID号的XML代码添加到清单中。 Just ridiculous.
太荒谬了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.