GDI+中graphics对象的获得【翻译自英文书籍《C# graphics programming》】

声明:只翻译了要点,忘见谅。

获得一个在其上绘画的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置否,以免生成更多页。

原文地址:https://www.cnblogs.com/hold/p/2286792.html