PrintDocument組件是用於完成打印的類,其常用屬性、方法和事件如下:
屬性DocumentName:字符串類型,記錄打印文檔時顯示的文檔名(例如,在打印狀態對話框或打印機隊列中顯示)。
方法Print:開始文檔的打印。
事件BeginPrint:在調用Print方法后,在打印文檔的第一頁之前發生。
事件PrintPage:需要打印新的一頁時發生。
事件EndPrint:在文檔的最后一頁打印后發生。
若要打印,首先創建PrintDocument組件的對象。然后使用頁面設置對話框PageSetupDialog設置頁面打印方式,這些設置作為要打印的所有頁的默認設置。使用打印對話框PrintDialog設置對文檔進行打印的打印機的參數。在打開兩個對話框前,首先設置對話框的屬性Document為指定的PrintDocument類對象,修改的設置將保存到PrintDocument組件對象中。第三步是調用PrintDocument.Print方法來實際打印文檔。當調用該方法后,引發下列事件:BeginPrint、PrintPage、EndPrint。其中每打印一頁都引發PrintPage事件,打印多頁,要多次引發PrintPage事件。完成一次打印,可以引發一個或多個PrintPage事件。
程序員應為這3個事件編寫事件處理函數。BeginPrint事件處理函數進行打印初始化,一般設置在打印時所有頁的相同屬性或共用的資源,例如所有頁共同使用的字體、建立要打印的文件流等。PrintPage事件處理函數負責打印一頁數據。EndPrint事件處理函數進行打印善后工作。這些處理函數的第2個參數System.Drawing.Printing.PrintEventArgs e提供了一些附加信息,主要有:
e.Cancel:布爾變量,設置為true,將取消這次打印作業。
e.Graphics:所使用的打印機的設備環境。
e.HasMorePages:布爾變量。PrintPage事件處理函數打印一頁后,仍有數據未打印,退出事件處理函數前設置HasMorePages=true,退出PrintPage事件處理函數后,將再次引發PrintPage事件,打印下一頁。
e.MarginBounds:打印區域的大小,是Rectangle結構,元素包括左上角坐標:Left和Top,寬和高:Width和Height。單位為1/100英寸。
e.MarginBounds:打印紙的大小,是Rectangle結構。單位為1/100英寸。
e.PageSettings:PageSettings類對象,包含用對話框PageSetupDialog設置的頁面打印方式的全部信息。可用幫助查看PageSettings類的屬性。
下邊為這3個事件編寫事件處理函數,具體步驟如下:
(1) 在最后一個using語句之后增加語句: using System.IO; using System.Drawing.Printing;
(2) 本例打印或預覽RichTextBox中的內容,增加變量:StringReader streamToPrint=null。如果打印或預覽文件,改為:StreamReader streamToPrint,流的概念參見第六章。增加打印使用的字體的變量:Font printFont。
(3) 放PrintDocument控件到窗體,屬性name為printDocument1。
(4) 為printDocument1增加BeginPrint事件處理函數如下: private void printDocument1_BeginPrint(object sender, System.Drawing.Printing.PrintEventArgs e) { printFont=richTextBox1.Font;//打印使用的字體 streamToPrint=new StringReader(richTextBox1.Text);//打印richTextBox1.Text }//如預覽文件改為:streamToPrint=new StreamReader("文件的路徑及文件名");
(5) printDocument1的PrintPage事件處理函數如下。streamToPrint.ReadLine()讀入一段數據,可能打印多行。本事件處理函數將此段數據打印在一行上,因此方法必須改進。 private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e) { float linesPerPage=0;//記錄每頁最大行數 float yPos=0;//記錄將要打印的一行數據在垂直方向的位置 int count=0;//記錄每頁已打印行數 float leftMargin=e.MarginBounds.Left;//左邊距 float topMargin=e.MarginBounds.Top;//頂邊距 string line=null;//從RichTextBox中讀取一段字符將存到line中 //每頁最大行數=一頁紙打印區域的高度/一行字符的高度 linesPerPage=e.MarginBounds.Height/printFont.GetHeight(e.Graphics); //如果當前頁已打印行數小於每頁最大行數而且讀出數據不為null,繼續打印 while(count<linesPerPage&&((line=streamToPrint.ReadLine())!=null)) { //yPos為要打印的當前行在垂直方向上的位置 yPos=topMargin+(count*printFont.GetHeight(e.Graphics)); e.Graphics.DrawString(line,printFont,Brushes.Black, leftMargin,yPos,new StringFormat());//打印,參見第五章 count++;//已打印行數加1 } if(line!=null)//是否需要打印下一頁 e.HasMorePages=true;//需要打印下一頁 else e.HasMorePages=false;//不需要打印下一頁 }
(6) 為printDocument1增加EndPrint事件處理函數如下: private void printDocument1_EndPrint (object sender, System.Drawing.Printing.PrintEventArgs e) { if(streamToPrint!=null) streamToPrint.Close();//釋放不用的資源 }