声明:只翻译了要点,忘见谅。
获得一个在其上绘画的Graphics对象的方法主要有四种:
1、调用一个窗体或者控件的CreateGraphics方法
2、调用Graphics类的FromImage方法
3、使用Paint事件处理函数中的e.Graphics参数
4、使用PrintDocument对象的PrintPage事件处理函数的e.Graphics参数
1.使用CreateGraphics
范例式使用语句为:
Graphics gr = this.CreateGraphics(); gr.FillEllipse(Brushes.Yellow, 10, 30, 200, 150); gr.DrawEllipse(Pens.Orange, 10, 30, 200, 150);
通过以上语句你将绘制出一个带有橘色边缘的黄色椭圆。
但是问题在于,当用一个窗体部分或者全部的遮挡这一绘制窗体或者控件,然后移开后,我们会发现这个椭圆会部分或者全部的消失。
2、使用FromImage
下面所示代码使用了一个PictureBox控件对象picEllipse,下面代码绘制了一个椭圆并以bitmap形式显示在picEllipse中。
// Create the Bitmap. Bitmap bm = new Bitmap(200, 100); // Get a Graphics object associated with the Bitmap. Graphics gr = Graphics.FromImage(bm); // Draw on the Bitmap. gr.FillEllipse(Brushes.Pink, 10, 10, 180, 80); gr.DrawEllipse(Pens.Black, 10, 10, 180, 80); // Display the Bitmap in the PictureBox. picEllipse.Image = bm;
该方法不会再遇到CreateGraphics中遇到的问题。文中提到“Building a bitmap by using the FromImage method is usually the best method for drawing permanent images.”
3、使用e.Graphics in Paint Event Handlers
代码如下:
private void Form1_Paint(object sender,PaintEventArgs e)
{ e.Graphics.Clear(this.BackColor);
e.Graphics.DrawLine(Pens.Blue, 0, 0,this.ClientSize.Width,this.ClientSize.Height);
e.Graphics.DrawLine(Pens.Blue, this.ClientSize.Width, 0, 0,this.ClientSize.Height);
}
该方法简单有效但是也存在一些问题。
当Form1窗体大小变化时此种方法仅会重绘变化的部分,而不会重绘原来的部分,所以当Form1窗体变化时绘制内容会显得非常诡异。
解决方法是在该窗体的Load方法中加入如下语句:
private void Form1_Load(object sender, EventArgs e) { this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.ResizeRedraw, true); }
应用在程序中可见如下代码:
另一个问题是如果在Paint事件处理方法中使用CreateGraphics,问题在于当Paint方法结束时所绘制的内容会丢失,所以切记不要在use CreateGraphics inside Paint event handlers. (事实上,我们应该尽量少用CreateGraphics)
4、使用e.Graphics in PrintPage Event Handle
当使用一个PrintDocument控件来进行打印时,该控件的对象会调用PrintPage事件来生成需要绘制的页面。
代码如下:
private void pdEllipse_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e) { e.Graphics.DrawEllipse(Pens.Green, e.MarginBounds); e.HasMorePages = false; }
其中使用e.MarginBounds使椭圆能填充整个页面,并在函数中将HasMorePages置否,以免生成更多页。