创建Graphics对象有以下三种方法。
从Form或Control的Paint事件的参数 PaintEventArgs中取得Graphics对象的引用,一般在Form或Control上画图,都使用这种方法。相似的,你也可以从PrintDocument的PrintPage事件的参数PrintPageEventArgs的属性中获得Graphics对象的引用。
1.1. 从PaintEventArgs获得Graphics对象的方法如下:using System; using System.Drawing; using System.Windows.Forms; namespace DrawingEg { public partial class FormDrawing1 : Form { private Rectangle rec = new Rectangle(); public FormDrawing1() { InitializeComponent(); } private void FormDrawing1_MouseDown(object sender, MouseEventArgs e) { // 获取起点 rec.Location = new Point(e.X, e.Y); } private void FormDrawing1_MouseUp(object sender, MouseEventArgs e) { // 设置图形的宽和高 rec.Width = Math.Abs(rec.X - e.X); rec.Height = Math.Abs(rec.Y - e.Y); // 把左上的点设置图形的顶点 if (e.X < rec.X) { rec.X = e.X; } if (e.Y < rec.Y) { rec.Y = e.Y; } // 重绘画面 this.Invalidate(); } // 使用重写OnPaint方法,可以实现同样的功能 // protected override void OnPaint(PaintEventArgs e) private void FormDrawing1_Paint(object sender, PaintEventArgs e) { // 获取Graphics对象的引用 Graphics g = e.Graphics; // 画矩形,如果要改变图形的位置和大小,修改rec的X, Y, Width, Height即可。 g.DrawRectangle(new Pen(Color.Red, 1), rec); } } }
1.2. 从PrintPageEventArgs的属性中获得Graphics对象的方法如下:
using System; using System.Drawing; using System.Drawing.Printing; using System.IO; using System.Windows.Forms; namespace DrawingEg { public partial class FormDrawing2 : Form { private Font printFont; private StreamReader streamToPrint; public FormDrawing2() { InitializeComponent(); } private void printButton_Click(object sender, EventArgs e) { try { // 获取要打印的文件的流 streamToPrint = new StreamReader ("D:\\Introduce.txt"); try { printFont = new Font("Arial", 10); PrintDocument pd = new PrintDocument(); pd.PrintPage += new PrintPageEventHandler (this.pd_PrintPage); // 触发PrintPage事件,把Introduce.txt内容打印到pdf文件 pd.Print(); } finally { streamToPrint.Close(); } } catch (Exception ex) { MessageBox.Show(ex.Message); } } private void pd_PrintPage(object sender, PrintPageEventArgs ev) { float linesPerPage = 0; float yPos = 0; int count = 0; float leftMargin = ev.MarginBounds.Left; float topMargin = ev.MarginBounds.Top; string line = null; // 根据字体的大小计算每页可以打印的行数 linesPerPage = ev.MarginBounds.Height / printFont.GetHeight(ev.Graphics); // 打印每行直到一页的最大行数 while (count < linesPerPage && ((line = streamToPrint.ReadLine()) != null)) { yPos = topMargin + (count * printFont.GetHeight(ev.Graphics)); ev.Graphics.DrawString(line, printFont, Brushes.Black, leftMargin, yPos, new StringFormat()); count++; } // 如果当前页没有把内容打印完,继续调用pd_PrintPage在下一页打印 if (line != null) { ev.HasMorePages = true; } else { ev.HasMorePages = false; } } } }
使用Control.CreateGraphics方法来获取Graphics对象的引用。通常使用这种方法在已经存在的Control或Form上绘图。注意: 通常这种方法取得的Graphics在当前的Windows 消息处理完后不应保留,因为与该对象相关的任何东西都将通过下个 WM_PAINT 消息清除。因此,无法缓存 Graphics 对象以重用,除非用非可视方法,如 Graphics.MeasureString。每次要使用 Graphics 对象时都必须调用 CreateGraphics,然后在用完时调用 Dispose。根据设计,CreateGraphics 将所属权设置为调用线程,并且如果在其他线程上调用,将会失败。
示例如下:using System; using System.Drawing; using System.Windows.Forms; namespace DrawingEg { public partial class FormDrawing3 : Form { public FormDrawing3() { InitializeComponent(); } private void AutoSizeControl(Control control) { // 为当前Control创建Graphics对象 Graphics g = control.CreateGraphics(); // 取得字符串的大小 Size contentSize = g.MeasureString( control.Text, control.Font).ToSize(); // Pad the text and resize the control. control.ClientSize = new Size(contentSize.Width, contentSize.Height); // 释放Graphics对象 g.Dispose(); } private void FormDrawing3_Load(object sender, EventArgs e) { /* Label的显示内容如下: * Hello! * My name is Steven. * What is your name? */ this.lblShowString.Text = "Hello!\r\nMy name is Steven.\r\nWhat is your name?"; AutoSizeControl(this.lblShowString); } } }
使用继承自Image的FromImage方法获取Graphics对象的引用。该方法通常用于在已经存在的图片上绘制图形。示例如下:
using System; using System.Drawing; using System.Windows.Forms; namespace DrawingEg { public partial class FormDrawing4 : Form { public FormDrawing4() { InitializeComponent(); } private void btnDraw_Click(object sender, EventArgs e) { // 获取Image对象 // 注意:如果该图像具有索引的像素格式,此方法将引发异常。这些格式如下: // System.Drawing.Imaging.PixelFormat.Format1bppIndexed // System.Drawing.Imaging.PixelFormat.Format4bppIndexed // System.Drawing.Imaging.PixelFormat.Format8bppIndexed Image img = Image.FromFile(@"D:\picture\test.bmp"); // 把Image对象赋给PictureBox picBox.Image = img; // 使用Graphics.FromImage获取Graphics对象 Graphics g = Graphics.FromImage(img); // 在test.bmp上画一个正方形 g.DrawRectangle(new Pen(Color.Red), 50, 50, 100, 100); // 应始终调用 Dispose 方法以释放 Graphics 和相关资源创建的 FromImage 方法。 g.Dispose(); } } }