打印『转载』
使用 Windows 窗体打印
重要的打印类:
PrintDocument |
PrintDocument 用于将输出发送到打印机。可实例化一个 PrintDocument,设置一些属性描述打印的内容,然后调用 Print 方法。PrintDocument 为要打印的每一页引发 PrintPage 事件。可向此事件的事件处理程序添加打印逻辑。 |
PrinterSettings |
有关应如何打印文档的信息。这包括在哪个打印机上打印该文档。 |
PageSettings |
有关应如何打印页的信息。 |
PrintPageEventArgs |
PrintDocument 上 PrintPage 事件的数据。它为打印图面提供剪辑矩形和 Graphics 对象。 |
PrintEventArgs |
PrintDocument 上 BeginPrint 和 EndPrint 事件的数据。允许取消打印作业。 |
PrintDialog |
打印机选项对话框。包装 Win32 PrintDlg API。 |
PageSetupDialog |
页属性对话框。包装 Win32 PageSetupDlg API。 |
PrintPreviewControl |
显示 PrintDocument 的控件。允许创建打印预览对话框。 |
PrintPreviewDialog |
通过使用 PrintPreviewControl 显示 PrintDocument 的对话框。 |
PrintController |
PrintController 控制如何打印 PrintDocument。PrintDocument.Print 使用打印控件呈现文档。 .NET 框架提供两个打印控制器:
通常,从来不必实现 PrintController。仅当要呈现到其他图面时才实现 PrintController。 |
生成进行打印的应用程序
了解打印类如何组合在一起的最简单的途径就是尝试完成一个简单示例,将一个文本文件的内容输出到打印机。
第 1 步:打印逻辑
需要做的第一件事是编写打印逻辑。这可通过处理 PrintDocument 上的事件来完成。当调用 PrintDocument.Print() 方法时,引发下列事件:
- BeginPrint
- PrintPage(一个或多个)
- EndPrint
PrintPage 事件的参数类型 (PrintPageEventArgs) 具有 HasMorePages 属性。如果在事件处理程序返回时,此属性设置为 true,则 PrintDocument 设置新页并再次引发 PrintPage 事件。
因此,PrintPage 事件处理程序中的逻辑基本上是:
- 使用事件参数中的信息打印页的内容。这些事件参数包含打印机的 Graphics、该页的 PageSettings、页的边界以及边距的大小。
- 确定是否还要打印其他页。
- 如果还有其他页,则将 HasMorePages 设置为 true。
- 如果没有其他页,则将 HasMorePages 设置为 false。
在最简单的情况下,可以作为包含打印请求的 Form 的一部分创建 PrintDocument 和处理 PrintPage 事件。
//Example Form that Prints public class PrintCtl : Form { Private string[] printBuffer ; Private Font printFont; Private int startLine; //Event fired when the user presses the print button private void print_Click(object sender, EventArgs e) { fileToPrint = new StreamReader ("PrintMe.Txt"); try { printFont = new Font("Arial", 10); PrintDocument pd = new PrintDocument(); //Assumes the default printer pd.PrintPage += new PrintPageEventHandler(this.pd_PrintPage); pd.Print(); } finally { fileToPrint.Close() ; } } //Event fired for each page to print private void pd_PrintPage(object sender, PrintPageEventArgs ev) { float lpp = 0 ; float yPos = 0 ; int count = 0 ; float leftMargin = ev.MarginBounds.Left; float topMargin = ev.MarginBounds.Top; String line=null; //Work out the number of lines per page //Use the MarginBounds on the event to do this lpp = ev.MarginBounds.Height / printFont.GetHeight(ev.Graphics) ; //Now iterate over the file printing out each line //NOTE WELL: This assumes that a single line is not wider than the page width //Check count first so that we don't read line that we won't print while (count < lpp && ((line=streamToPrint.ReadLine()) != null)) { yPos = topMargin + (count * printFont.GetHeight(ev.Graphics)); //Print Preview control will not work. ev.Graphics.DrawString (line, printFont, Brushes.Black, leftMargin, yPos, new StringFormat()); count++; } //If we have more lines then print another page if (line != null) ev.HasMorePages = true ; else ev.HasMorePages = false ; } .... } | ||
C# | VB |
查看并运行此示例。
[运行示例] | [查看源代码] |
第 2 步:定义自己的打印文档
对于复杂的打印作业或要在多个窗体间重复使用的打印逻辑,可以从 PrintDocument 派生一个新类,并将打印逻辑封装到该类中。在这种情况下,请通过重写 OnPrintPage 方法而不是使用事件处理程序来处理 PrintPage 事件。
public class TextFilePrintDocument : PrintDocument { private Font printFont = null ; private StreamReader streamToPrint = null ; public TextFilePrintDocument(StreamReader streamToPrint) : base () { this.streamToPrint = streamToPrint ; } //Override OnBeginPrint to set up the font we are going to use protected override void OnBeginPrint(PrintEventArgs ev) { base.OnBeginPrint(ev) ; printFont = new Font("Arial", 10); } //Override the OnPrintPage to provide the printing logic for the document protected override void OnPrintPage(PrintPageEventArgs ev) { base.OnPrintPage(ev) ; float lpp = 0 ; float yPos = 0 ; int count = 0 ; float leftMargin = ev.MarginBounds.Left; float topMargin = ev.MarginBounds.Top; String line=null; //Work out the number of lines per page //Use the MarginBounds on the event to do this lpp = ev.MarginBounds.Height / printFont.GetHeight(ev.Graphics) ; //Now iterate over the file printing out each line //NOTE WELL: This assumes that a single line is not wider than the page width //Check count first so that we don't read line that we won't print while (count < lpp && ((line=streamToPrint.ReadLine()) != null)) { yPos = topMargin + (count * printFont.GetHeight(ev.Graphics)); //Print Preview control will not work. ev.Graphics.DrawString (line, printFont, Brushes.Black, leftMargin, yPos, new StringFormat()); count++; } //If we have more lines then print another page if (line != null) ev.HasMorePages = true ; else ev.HasMorePages = false ; } } | ||
C# | VB |
查看并运行此示例。
[运行示例] | [查看源代码] |
第 3 步:允许用户选择打印机
在打印逻辑工作正常以后,下一步是允许用户使用 Windows"打印"对话框选择打印机。为此,创建 PrintDocument 并将其传递给 PrintDialog。
//Event fired when the user presses the print button private void printButton_Click(object sender, EventArgs e) { StreamReader streamToPrint = new StreamReader ("PrintMe.Txt"); try { //Assumes the default printer TextFilePrintDocument pd = new TextFilePrintDocument(streamToPrint); PrintDialog dlg = new PrintDialog() ; dlg.Document = pd; DialogResult result = dlg.ShowDialog(); if (result == DialogResult.OK) { pd.Print(); } } finally { streamToPrint.Close() ; } } | ||
C# | VB |
查看并运行此示例。
[运行示例] | [查看源代码] |
第 4 步:允许用户选择页面设置
用户可以选择打印机并打印文档后,可以允许他们选择页面设置,如纸张方向或边距大小。为此,创建 PageSettings 实例并将其传递给 PageSetupDialog。
//Event fired when the user presses the page setup button private void pageSetupButton_Click(object sender, EventArgs e) { PageSetupDialog psDlg = new PageSetupDialog() ; if (storedPageSettings == null) { storedPageSettings = new PageSettings(); } psDlg.PageSettings = storedPageSettings ; psDlg.ShowDialog(); } | ||
C# | VB |
然后可在用户打印文档时使用此自定义 PageSettings 实例。
//Event fired when the user presses the print button private void printButton_Click(object sender, EventArgs e) { StreamReader streamToPrint = new StreamReader ("PrintMe.Txt"); try { TextFilePrintDocument pd = new TextFilePrintDocument(streamToPrint); if (storedPageSettings != null) { pd.DefaultPageSettings = storedPageSettings ; } PrintDialog dlg = new PrintDialog() ; dlg.Document = pd; DialogResult result = dlg.ShowDialog(); if (result == DialogResult.OK) { pd.Print(); } } finally { streamToPrint.Close() ; } } | ||
C# | VB |
查看并运行此示例。
[运行示例] | [查看源代码] |
第 5 步:显示“打印预览”窗口
“打印预览”窗口使用户得以在打印他们的文档前预览该文档。可以通过创建 PrintDocument 并将其传递到 PrintPreview 对话框,将“打印预览”窗口添加到应用程序中。
//Event fired when the user presses the print preview button private void printPreviewButton_Click(object sender, EventArgs e) { StreamReader streamToPrint = new StreamReader ("PrintMe.Txt"); try { TextFilePrintDocument pd = new TextFilePrintDocument(streamToPrint); if (storedPageSettings != null) { pd.DefaultPageSettings = storedPageSettings ; } PrintPreviewDialog dlg = new PrintPreviewDialog() ; dlg.Document = pd; dlg.ShowDialog(); } finally { streamToPrint.Close() ; } } | ||
C# | VB |
查看并运行此示例。
[运行示例] | [查看源代码] |
将所有内容组合在一起
Windows 窗体示例包括一个名为 SimplePad 的示例,该示例显示如何生成一个打印正在编辑的文件的简单文本编辑器。
[运行示例] | [查看源代码] |