如何:使用打印预览在 Windows 窗体中进行打印
在 Windows 窗体编程中,除打印服务外还提供打印预览,这是很常见的。 要将打印预览服务添加到应用程序中,一种简便方式是将 PrintPreviewDialog 控件与 PrintPage 事件处理逻辑结合使用以打印文件。
使用 PrintPreviewDialog 控件预览文本文档
向窗体添加 PrintPreviewDialog、PrintDocument 以及两个字符串。
Private printPreviewDialog1 As New PrintPreviewDialog() Private WithEvents printDocument1 As New PrintDocument() ' Declare a string to hold the entire document contents. Private documentContents As String ' Declare a variable to hold the portion of the document that ' is not printed. Private stringToPrint As String
private PrintPreviewDialog printPreviewDialog1 = new PrintPreviewDialog(); private PrintDocument printDocument1 = new PrintDocument(); // Declare a string to hold the entire document contents. private string documentContents; // Declare a variable to hold the portion of the document that // is not printed. private string stringToPrint;
将 DocumentName 属性设置为要打印的文档,然后打开并读取文档内容到以前添加的字符串。
Private Sub ReadDocument() Dim docName As String = "testPage.txt" Dim docPath As String = "c:\" printDocument1.DocumentName = docName Dim stream As New FileStream(docPath + docName, FileMode.Open) Try Dim reader As New StreamReader(stream) Try documentContents = reader.ReadToEnd() Finally reader.Dispose() End Try Finally stream.Dispose() End Try stringToPrint = documentContents End Sub
private void ReadDocument() { string docName = "testPage.txt"; string docPath = @"c:\"; printDocument1.DocumentName = docName; using (FileStream stream = new FileStream(docPath + docName, FileMode.Open)) using (StreamReader reader = new StreamReader(stream)) { documentContents = reader.ReadToEnd(); } stringToPrint = documentContents; }
与打印文档时一样,在 PrintPage 事件处理程序中,使用 PrintPageEventArgs 类的 Graphics 属性以及文件内容来计算每页行数并呈现文档内容。 每一页绘制后,检查该页是否是最后一页,并相应设置 PrintPageEventArgs 的 HasMorePages 属性。 引发 PrintPage 事件,直到 HasMorePages 为 false。 文档完成呈现后,重置要呈现的字符串。 此外,确保 PrintPage 事件与其事件处理方法关联。
提示
如果您已在应用程序中实现打印,则可能已经完成了步骤 2 和 3。
在下面的代码示例中,事件处理程序用于以窗体上所用的相同字体打印“testPage.txt”文件。
Sub printDocument1_PrintPage(ByVal sender As Object, _ ByVal e As PrintPageEventArgs) Handles printDocument1.PrintPage Dim charactersOnPage As Integer = 0 Dim linesPerPage As Integer = 0 ' Sets the value of charactersOnPage to the number of characters ' of stringToPrint that will fit within the bounds of the page. e.Graphics.MeasureString(stringToPrint, Me.Font, e.MarginBounds.Size, _ StringFormat.GenericTypographic, charactersOnPage, linesPerPage) ' Draws the string within the bounds of the page. e.Graphics.DrawString(stringToPrint, Me.Font, Brushes.Black, _ e.MarginBounds, StringFormat.GenericTypographic) ' Remove the portion of the string that has been printed. stringToPrint = stringToPrint.Substring(charactersOnPage) ' Check to see if more pages are to be printed. e.HasMorePages = stringToPrint.Length > 0 ' If there are no more pages, reset the string to be printed. If Not e.HasMorePages Then stringToPrint = documentContents End If End Sub
void printDocument1_PrintPage(object sender, PrintPageEventArgs e) { int charactersOnPage = 0; int linesPerPage = 0; // Sets the value of charactersOnPage to the number of characters // of stringToPrint that will fit within the bounds of the page. e.Graphics.MeasureString(stringToPrint, this.Font, e.MarginBounds.Size, StringFormat.GenericTypographic, out charactersOnPage, out linesPerPage); // Draws the string within the bounds of the page. e.Graphics.DrawString(stringToPrint, this.Font, Brushes.Black, e.MarginBounds, StringFormat.GenericTypographic); // Remove the portion of the string that has been printed. stringToPrint = stringToPrint.Substring(charactersOnPage); // Check to see if more pages are to be printed. e.HasMorePages = (stringToPrint.Length > 0); // If there are no more pages, reset the string to be printed. if (!e.HasMorePages) stringToPrint = documentContents; }
将 PrintPreviewDialog 控件的 Document 属性设置为窗体上的 PrintDocument 组件。
printPreviewDialog1.Document = printDocument1
printPreviewDialog1.Document = printDocument1;
调用 PrintPreviewDialog 控件上的 ShowDialog 方法。 通常您将从按钮的 Click 事件处理方法调用 ShowDialog。 调用 ShowDialog 会引发 PrintPage 事件,并将输出呈现到 PrintPreviewDialog 控件。 当用户单击对话框上的打印图标时,会再次引发 PrintPage 事件,将输出发送到打印机而非预览对话框。 正因为如此,字符串会在步骤 3 中的呈现过程结束时被重置。
下面的代码示例演示窗体上某个按钮的 Click 事件处理方法。 此事件处理方法调用各种方法以读取文档并显示打印预览对话框。
Private Sub printPreviewButton_Click(ByVal sender As Object, _ ByVal e As EventArgs) Handles printPreviewButton.Click ReadDocument() printPreviewDialog1.Document = printDocument1 printPreviewDialog1.ShowDialog() End Sub
private void printPreviewButton_Click(object sender, EventArgs e) { ReadDocument(); printPreviewDialog1.Document = printDocument1; printPreviewDialog1.ShowDialog(); }
示例
Imports System
Imports System.Drawing
Imports System.IO
Imports System.Drawing.Printing
Imports System.Windows.Forms
Class Form1
Inherits Form
Private WithEvents printPreviewButton As Button
Private printPreviewDialog1 As New PrintPreviewDialog()
Private WithEvents printDocument1 As New PrintDocument()
' Declare a string to hold the entire document contents.
Private documentContents As String
' Declare a variable to hold the portion of the document that
' is not printed.
Private stringToPrint As String
Public Sub New()
Me.printPreviewButton = New System.Windows.Forms.Button()
Me.printPreviewButton.Location = New System.Drawing.Point(12, 12)
Me.printPreviewButton.Size = New System.Drawing.Size(125, 23)
Me.printPreviewButton.Text = "Print Preview"
Me.ClientSize = New System.Drawing.Size(292, 266)
Me.Controls.Add(Me.printPreviewButton)
End Sub
Private Sub ReadDocument()
Dim docName As String = "testPage.txt"
Dim docPath As String = "c:\"
printDocument1.DocumentName = docName
Dim stream As New FileStream(docPath + docName, FileMode.Open)
Try
Dim reader As New StreamReader(stream)
Try
documentContents = reader.ReadToEnd()
Finally
reader.Dispose()
End Try
Finally
stream.Dispose()
End Try
stringToPrint = documentContents
End Sub
Sub printDocument1_PrintPage(ByVal sender As Object, _
ByVal e As PrintPageEventArgs) Handles printDocument1.PrintPage
Dim charactersOnPage As Integer = 0
Dim linesPerPage As Integer = 0
' Sets the value of charactersOnPage to the number of characters
' of stringToPrint that will fit within the bounds of the page.
e.Graphics.MeasureString(stringToPrint, Me.Font, e.MarginBounds.Size, _
StringFormat.GenericTypographic, charactersOnPage, linesPerPage)
' Draws the string within the bounds of the page.
e.Graphics.DrawString(stringToPrint, Me.Font, Brushes.Black, _
e.MarginBounds, StringFormat.GenericTypographic)
' Remove the portion of the string that has been printed.
stringToPrint = stringToPrint.Substring(charactersOnPage)
' Check to see if more pages are to be printed.
e.HasMorePages = stringToPrint.Length > 0
' If there are no more pages, reset the string to be printed.
If Not e.HasMorePages Then
stringToPrint = documentContents
End If
End Sub
Private Sub printPreviewButton_Click(ByVal sender As Object, _
ByVal e As EventArgs) Handles printPreviewButton.Click
ReadDocument()
printPreviewDialog1.Document = printDocument1
printPreviewDialog1.ShowDialog()
End Sub
<STAThread()> _
Shared Sub Main()
Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(False)
Application.Run(New Form1())
End Sub
End Class
using System;
using System.Drawing;
using System.IO;
using System.Drawing.Printing;
using System.Windows.Forms;
namespace PrintPreviewApp
{
public partial class Form1 : Form
{
private Button printPreviewButton;
private PrintPreviewDialog printPreviewDialog1 = new PrintPreviewDialog();
private PrintDocument printDocument1 = new PrintDocument();
// Declare a string to hold the entire document contents.
private string documentContents;
// Declare a variable to hold the portion of the document that
// is not printed.
private string stringToPrint;
public Form1()
{
this.printPreviewButton = new System.Windows.Forms.Button();
this.printPreviewButton.Location = new System.Drawing.Point(12, 12);
this.printPreviewButton.Size = new System.Drawing.Size(125, 23);
this.printPreviewButton.Text = "Print Preview";
this.printPreviewButton.Click += new System.EventHandler(this.printPreviewButton_Click);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.Add(this.printPreviewButton);
printDocument1.PrintPage +=
new PrintPageEventHandler(printDocument1_PrintPage);
}
private void ReadDocument()
{
string docName = "testPage.txt";
string docPath = @"c:\";
printDocument1.DocumentName = docName;
using (FileStream stream = new FileStream(docPath + docName, FileMode.Open))
using (StreamReader reader = new StreamReader(stream))
{
documentContents = reader.ReadToEnd();
}
stringToPrint = documentContents;
}
void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
{
int charactersOnPage = 0;
int linesPerPage = 0;
// Sets the value of charactersOnPage to the number of characters
// of stringToPrint that will fit within the bounds of the page.
e.Graphics.MeasureString(stringToPrint, this.Font,
e.MarginBounds.Size, StringFormat.GenericTypographic,
out charactersOnPage, out linesPerPage);
// Draws the string within the bounds of the page.
e.Graphics.DrawString(stringToPrint, this.Font, Brushes.Black,
e.MarginBounds, StringFormat.GenericTypographic);
// Remove the portion of the string that has been printed.
stringToPrint = stringToPrint.Substring(charactersOnPage);
// Check to see if more pages are to be printed.
e.HasMorePages = (stringToPrint.Length > 0);
// If there are no more pages, reset the string to be printed.
if (!e.HasMorePages)
stringToPrint = documentContents;
}
private void printPreviewButton_Click(object sender, EventArgs e)
{
ReadDocument();
printPreviewDialog1.Document = printDocument1;
printPreviewDialog1.ShowDialog();
}
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}
编译代码
此示例需要:
对 System、System.Windows.Forms、System.Drawing 程序集的引用。
有关从 Visual Basic 或 Visual C# 的命令行生成此示例的信息,请参见从命令行生成 (Visual Basic) 或在命令行上使用 csc.exe 生成。 也可以通过将代码粘贴到新项目,在 Visual Studio 中生成此示例。 有关更多信息,请参见 如何:使用 Visual Studio 编译和运行完整的 Windows 窗体代码示例 和 如何:使用 Visual Studio 编译和运行完整的 Windows 窗体代码示例 和 如何:使用 Visual Studio 编译和运行完整的 Windows 窗体代码示例 和 如何:使用 Visual Studio 编译和运行完整的 Windows 窗体代码示例 和 如何:使用 Visual Studio 编译和运行完整的 Windows 窗体代码示例.