前言:
在项目或者学习过程中我们经常会使用到C#自带的GDI绘图技术,
在我之前几篇文章里也有用到绘图技术
画五角星
基本步骤:
- 创建Graphics对象
- 创建Pen对象
- 调用Graphics类中封装的绘制方法(绘制直线,曲线,圆)
问题:
在前一篇文章中贪吃蛇V1.0
我想给游戏界面添加网格线,让界面看起来舒服。
然而在这过程中我遇到了问题
- 我最开始的思路为在Form1的load事件中为窗体绘制网格线
网格线的绘制代码,如下:
int col = 50;
int row = 50;
int drawRow = 0;
int drawCol = 0;
Pen black = new Pen(Color.Gray, 1);
Graphics g = this.CreateGraphics();
for (int i = 0; i <= row; i++)
{
g.DrawLine(black, 0, drawCol, 500, drawCol);
drawCol += 10;
}
// 画垂直线
for (int j = 0; j <= col; j++)
{
g.DrawLine(black, drawRow, 0, drawRow, 500);
drawRow += 10;
}
但是当我运行Form1的时候发现窗体中并没有出现网格线,我反复检查我的代码发现并没有问题,
问题原因:
Form_Load事件是在窗体首次显示时发生的。
也就是说,在Form_Load过程中,这个Form里所有需要在屏幕上呈现的东西都还没开始绘制,所以你在Load中去绘制东西是看不到的。在Windows系统中,窗体的Load事件执行完毕后,系统才开始绘制窗体并显示在屏幕上。
其实,只有当Form_Load方法执行完后,我们才能看见窗体。
当Form_Paint方法执行完后才显示出我们想要绘制的完整的图形。并且窗体Repaint后,窗体的Graphics就被清空了。每次刷新的时候都需要绘制,在窗体Load也会刷新。
解决方法:
所以,在为窗体初始化的过程中绘制网格线,就得在窗体的Paint事件中创建Graphics对象,
方法为:
- 通过调用窗体的CreateGraphics方法来获取对Graphics对象的引用;
private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = this.CreateGraphics();
}
- 通过在窗体的Paint事件中创建,将其作为PaintEventArgs的一部分
private void Form1_Paint(object sender, PaintEventArgs e)
{
Graphics g = e.Graphics;
}
总结:
就是不要将为窗体绘制网格的代码,放在From_Load事件中,要放在Form_Paint事件中
补充:
创建Graphics对象的方法,除了上述两种外还有一种:
由从Image继承的如何对象创建Graphics对象
private void Form1_Load(object sender, EventArgs e)
{
Bitmap bitmap = new Bitmap(@"C:\is.bmp");
Graphics g = Graphics.FormImage(bitmap);
}