为什么PaintEventArgs.图形的行为与Control.CreateGraphics不同
本文关键字:Control CreateGraphics 不同 PaintEventArgs 图形 为什么 | 更新日期: 2023-09-27 18:15:40
我已经编写了一个事件处理程序方法,并将其附加到Form
的Paint
事件(只是主窗口)。这个事件发送一个包含Graphics
属性的PaintEventArgs
,它是System.Drawing.Graphics
的一个实例。
private void Form1_Paint(object sender, PaintEventArgs e) {
Bitmap bm = new Bitmap("fruit-dealer-full.jpg");
Graphics g1 = this.CreateGraphics();
Graphics g2 = e.Graphics;
// g1.DrawImage(bm, 0, 0, this.Width, this.Height);
// g1.DrawRectangle(
// Pens.White, 10.0f, 10.0f, this.Width - 200, this.Height - 200);
g2.DrawImage(bm, 0, 0, this.Width, this.Height);
g2.DrawRectangle(
Pens.White, 10.0f, 10.0f, this.Width - 200, this.Height - 200);
}
最后,我只是想更好地理解这里发生了什么,但具体来说,我有这三个问题:
- 为什么
g1
在整个窗口中重新绘制图像,而g2
只绘制新部分,即使我在绘制之前调用g2.Clear()
? - 为什么,无论是
Graphics
对象,是图像只重绘时,窗口的大小增加,而不是当它变小? - 如果
PaintEventArgs.Graphics
可以(或不应该)不用于绘图,它用于什么?我想它只是防止你不得不创建一个新的Graphics
实例,如果窗体不需要重新绘制;还有什么是我错过的吗?
你们这些. net WinForms孩子真的应该学习Win32 API。快去买一本佩佐德的书!
为什么g1在整个窗口中重新绘制图像,而g2只绘制新的部分,即使我在绘制之前调用g2. clear () ?
假设g2
是对从BeginPaint
接收到的设备上下文的包装器。我想WinForms会为你包装PAINTSTRUCT::rcPaint
——这个变量描述了要绘制的区域。这是预期的行为-而不是消耗CPU周期重新绘制你的整个窗口,每次另一个窗口重叠它只是一个像素,你可以重新绘制…只有一个像素!
g2.Clear
可能受到rcPaint
的限制。
g1
可能是窗口的GetDC
-它给了你整个表面来绘制。
为什么,无论是图形对象,是图像只有重新绘制时,窗口的大小增加,而不是当它变小?
底层窗口类可能没有CS_HREDRAW
或CS_VREDRAW
窗口样式。如果没有这些,当窗口变小时,默认行为就没有理由要求您重新绘制窗口:Windows知道整个窗口的样子,它可以将不需要的部分剪掉。这与窗口变大时不同,它不知道在新区域画什么。
如果PaintEventArgs。图形可以(或不应该)用于绘图,它的用途是什么?我想它只是防止你不得不创建一个新的图形实例,如果窗体不需要重新绘制;还有什么是我错过的吗?
是用来画画的。除非你有一些复杂的绘图要求,你可以使用PaintEventArgs.Graphics
最小化你的窗口上的绘画量。(如上所述-这是一个巨大的CPU周期节省器,它可能是BeginPaint
和EndPaint
的简单包装-这就是如何绘制到客户端区域。)
- 为什么g1在整个窗口中重新绘制图像,而g2只绘制新部分,即使我在绘制之前调用g2. clear () ?
我不明白这一点,你在两种情况下都画得很完整。所以两者都应该绘制整个表单,也许你在不同的代码中有这种行为 - 为什么,无论是图形对象,是图像只有重新绘制时,窗口的大小增加,而不是当它变小?
因为你应该在Form中调用Invalidate()。调整大小事件以启动重绘 如果PaintEventArgs - 。图形可以(或不应该)用于绘图,它的用途是什么?我想它只是防止你不得不创建一个新的图形实例,如果窗体不需要重新绘制;还有什么是我错过的吗?
它们是不同的,CreateGraphics是一个临时对象,应该在使用后立即处理(或在using块中使用),它用于不需要绘图的简单任务,例如MeasureString或获取上下文信息。对于绘图,你总是应该使用PaintEventArgs.Graphics。当使用双缓冲时,差异将是明显的,如果你使用CreateGraphics获得图形对象,你将获得控件的图形对象,而从PaintEventArgs获得它将获得缓冲位图。