e.Graphics 用法
e.Graphics usage
我发现绘图事件中的图形 g 和 e.Graphics 之间存在差异 .. e.Graphics 类似于 "more PRO",它允许使用转换矩阵获得更多乐趣。
这样的转换 https://msdn.microsoft.com/en-us/library/eews39w7(v=vs.110).aspx
我正在编写应用程序,其中会有几个对象。在这个问题中有例子
我在这里找到了如何覆盖 OnPaint 方法 https://msdn.microsoft.com/en-us/library/b818z6z6(v=vs.71).aspx
想不明白的是usecase我应该怎么用。我需要覆盖 OnPaint 方法 - 好的,但是在什么对象上?
让我们想象一下我将在 c# 中使用 Form 的简单情况
public partial class Form1 : Form {
private Bitmap canvasBitmap; //bitmap for drawing
private Graphics g;
...
public Form1() {
//on Form there is placed PictureBox called canvas
//so canvas is PictureBox 640x480 px
canvasBitmap = new Bitmap(canvas.Width, canvas.Height);
canvas.Image = canvasBitmap;
//prepare graphics
g = Graphics.FromImage(canvasBitmap);
g.SmoothingMode = SmoothingMode.AntiAlias;
...
g.Invalidate();
}
}
所有绘图都将在我的 PictureBox 上完成 canvas。可以保留图形 g 而不是 e.Graphics?
比我有一些对象:
List<Fish> fishes = new List<Fish>();
List<Food> food = new List<Food>();
而且我想和他们一起做一些有趣的事情,例如像这里这样的一些转换(缩放、平移、旋转)
https://msdn.microsoft.com/en-us/library/eews39w7(v=vs.110).aspx
这是对象。我试着写那个 OnPaint 方法(不确定它是否在正确的地方。)
class Fish {
Point position;
Fish(int x, int y) {
...
}
protected override void OnPaint(PaintEventArgs e){
...
}
}
class Food {
Point position;
public Food(int x, int y) {
...
}
protected override void OnPaint(PaintEventArgs pe) {
....
}
}
问题是:这种情况下应该如何使用OnPaint方法?使用这个的用例是什么?我想我可能会像我做的那样在 Fish 和 Food 对象上重写这个方法。我怎么画呢?我如何重绘它?我怎么把它放在我的Graphics g canvas Form里? Invalidate应该在哪里以及如何使用?
通常我使用
canvas.Invalidate();
查看表单示例。
我可以混合使用 Graphics g 和 e.Graphics 吗? e.Graphics 也可以使用一些双缓冲或类似的东西。
编辑
E1)所以Form和PicutreBox是控件?我的鱼和食物class不受控制?好的?
E2) 在 Picture box 上最多可以有 3 个图形,我可以切换它,以便平滑绘图。但为了简单起见,我可以留下一个吗?好吗?
E3) Graphics g 是工具 e.Graphics 是一些图形库的包装器,其中包含一些对转换(使用转换矩阵)的支持。好吗?
E4) OnPaint(PaintEventArgs e)
将使我能够使用 e.Graphics,但是如果我在计时器中有我的 "loop"(在我简单地放置的计时器对象的句柄中在我的表格上并设置时间段),然后我从中调用更新方法并更新某些列表中的所有鱼类和食物对象(更新 = 根据我的计算对它们进行转换)。有可能在这里使用 e.Graphics 的方法吗?
E5)如果E1为真,Food和Fish中的重写OnPaint方法class是废话好吗?
e.Graphics
来自 OnPaint
或 Paint
事件,因此 仅适用于控件 。
您从位图创建的Graphics
对象仅适用于该位图。
您应该使用您真正想要的:在表面上绘制 或 成位图。
请注意,位图可能会或可能不会显示在控件中(在表面下方)。
例如,一个图片框甚至可以在其表面下方显示 两个 个位图,因此您可能需要使用 三个 Graphics
对象..
他们对不同像素做相同的事情,不,你不能用一个做更多..!您可以应用矩阵和其他变换。
从 OnPaint
参数中获取 e.Graphics
的原因是系统有时需要重新绘制表单中的所有控件,因此必须另外调用您的绘图代码到内部控制绘图例程。
因此您需要使用此事件 and/or 其 e.Graphics
否则您的绘图将在此类重绘时消失。使用 e.Graphics
绘制到控件上将使绘图 persist。 (*)
另一方面,位图将始终以其当前状态显示。无需重新绘制它们;只需在完成更改后调用 Refresh()
一次,让系统知道它们。
最后:DoubleBuffering
是一个 属性 控件,而不是 Graphics
对象。请注意,对于大多数容器(尤其是像 Panel 这样的容器)来说,它是隐藏的,因此要打开它,您需要对它们进行子类化。 PictureBox
用于绘图,开箱即用 DoubleBuffered = true
。
Graphics
对象 不包含 任何图形;它是一个 工具,可让您在相关位图(包括控件表面)上绘图。
(*) 请注意,并非所有 绘图都需要或应该保留:橡皮筋线或矩形 不应该,在这里你使用第三个 Graphics
构造函数:Graphics g = someControl.CreateGraphics();
.
我发现绘图事件中的图形 g 和 e.Graphics 之间存在差异 .. e.Graphics 类似于 "more PRO",它允许使用转换矩阵获得更多乐趣。
这样的转换 https://msdn.microsoft.com/en-us/library/eews39w7(v=vs.110).aspx
我正在编写应用程序,其中会有几个对象。在这个问题中有例子
我在这里找到了如何覆盖 OnPaint 方法 https://msdn.microsoft.com/en-us/library/b818z6z6(v=vs.71).aspx
想不明白的是usecase我应该怎么用。我需要覆盖 OnPaint 方法 - 好的,但是在什么对象上?
让我们想象一下我将在 c# 中使用 Form 的简单情况
public partial class Form1 : Form {
private Bitmap canvasBitmap; //bitmap for drawing
private Graphics g;
...
public Form1() {
//on Form there is placed PictureBox called canvas
//so canvas is PictureBox 640x480 px
canvasBitmap = new Bitmap(canvas.Width, canvas.Height);
canvas.Image = canvasBitmap;
//prepare graphics
g = Graphics.FromImage(canvasBitmap);
g.SmoothingMode = SmoothingMode.AntiAlias;
...
g.Invalidate();
}
}
所有绘图都将在我的 PictureBox 上完成 canvas。可以保留图形 g 而不是 e.Graphics?
比我有一些对象:
List<Fish> fishes = new List<Fish>();
List<Food> food = new List<Food>();
而且我想和他们一起做一些有趣的事情,例如像这里这样的一些转换(缩放、平移、旋转) https://msdn.microsoft.com/en-us/library/eews39w7(v=vs.110).aspx
这是对象。我试着写那个 OnPaint 方法(不确定它是否在正确的地方。)
class Fish {
Point position;
Fish(int x, int y) {
...
}
protected override void OnPaint(PaintEventArgs e){
...
}
}
class Food {
Point position;
public Food(int x, int y) {
...
}
protected override void OnPaint(PaintEventArgs pe) {
....
}
}
问题是:这种情况下应该如何使用OnPaint方法?使用这个的用例是什么?我想我可能会像我做的那样在 Fish 和 Food 对象上重写这个方法。我怎么画呢?我如何重绘它?我怎么把它放在我的Graphics g canvas Form里? Invalidate应该在哪里以及如何使用?
通常我使用
canvas.Invalidate();
查看表单示例。 我可以混合使用 Graphics g 和 e.Graphics 吗? e.Graphics 也可以使用一些双缓冲或类似的东西。
编辑
E1)所以Form和PicutreBox是控件?我的鱼和食物class不受控制?好的?
E2) 在 Picture box 上最多可以有 3 个图形,我可以切换它,以便平滑绘图。但为了简单起见,我可以留下一个吗?好吗?
E3) Graphics g 是工具 e.Graphics 是一些图形库的包装器,其中包含一些对转换(使用转换矩阵)的支持。好吗?
E4) OnPaint(PaintEventArgs e)
将使我能够使用 e.Graphics,但是如果我在计时器中有我的 "loop"(在我简单地放置的计时器对象的句柄中在我的表格上并设置时间段),然后我从中调用更新方法并更新某些列表中的所有鱼类和食物对象(更新 = 根据我的计算对它们进行转换)。有可能在这里使用 e.Graphics 的方法吗?
E5)如果E1为真,Food和Fish中的重写OnPaint方法class是废话好吗?
e.Graphics
来自 OnPaint
或 Paint
事件,因此 仅适用于控件 。
您从位图创建的Graphics
对象仅适用于该位图。
您应该使用您真正想要的:在表面上绘制 或 成位图。
请注意,位图可能会或可能不会显示在控件中(在表面下方)。
例如,一个图片框甚至可以在其表面下方显示 两个 个位图,因此您可能需要使用 三个 Graphics
对象..
他们对不同像素做相同的事情,不,你不能用一个做更多..!您可以应用矩阵和其他变换。
从 OnPaint
参数中获取 e.Graphics
的原因是系统有时需要重新绘制表单中的所有控件,因此必须另外调用您的绘图代码到内部控制绘图例程。
因此您需要使用此事件 and/or 其 e.Graphics
否则您的绘图将在此类重绘时消失。使用 e.Graphics
绘制到控件上将使绘图 persist。 (*)
另一方面,位图将始终以其当前状态显示。无需重新绘制它们;只需在完成更改后调用 Refresh()
一次,让系统知道它们。
最后:DoubleBuffering
是一个 属性 控件,而不是 Graphics
对象。请注意,对于大多数容器(尤其是像 Panel 这样的容器)来说,它是隐藏的,因此要打开它,您需要对它们进行子类化。 PictureBox
用于绘图,开箱即用 DoubleBuffered = true
。
Graphics
对象 不包含 任何图形;它是一个 工具,可让您在相关位图(包括控件表面)上绘图。
(*) 请注意,并非所有 绘图都需要或应该保留:橡皮筋线或矩形 不应该,在这里你使用第三个 Graphics
构造函数:Graphics g = someControl.CreateGraphics();
.