# How to: Print in Windows Forms Using Print Preview

It is very common in Windows Forms programming to offer print preview in addition to printing services. An easy way to add print preview services to your application is to use a PrintPreviewDialog control in combination with the PrintPage event-handling logic for printing a file.

### To preview a text document with a PrintPreviewDialog control

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;

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

2. Set the DocumentName property to the document you wish to print, and open and read the document's contents to the string you added previously.

private void ReadDocument()
{
string docName = "testPage.txt";
string docPath = @"c:\";
printDocument1.DocumentName = docName;
using (FileStream stream = new FileStream(docPath + docName, FileMode.Open))
{
}
stringToPrint = documentContents;
}

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
Try
Finally
End Try
Finally
stream.Dispose()
End Try
stringToPrint = documentContents

End Sub

3. As you would for printing the document, in the PrintPage event handler, use the Graphics property of the PrintPageEventArgs class and the file contents to calculate lines per page and render the document's contents. After each page is drawn, check to see if it is the last page, and set the HasMorePages property of the PrintPageEventArgs accordingly. The PrintPage event is raised until HasMorePages is false. When the document has finished rendering, reset the string to be rendered. Also, make sure the PrintPage event is associated with its event-handling method.

Note

You may have already completed steps 2 and 3 if you have implemented printing in your application.

In the following code example, the event handler is used to print the "testPage.txt" file in the same font used on the form.

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;
}

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

4. Set the Document property of the PrintPreviewDialog control to the PrintDocument component on the form.

printPreviewDialog1.Document = printDocument1;

printPreviewDialog1.Document = printDocument1

5. Call the ShowDialog method on the PrintPreviewDialog control. You would typically call ShowDialog from the Click event-handling method of a button. Calling ShowDialog raises the PrintPage event and renders the output to the PrintPreviewDialog control. When the user clicks the print icon on the dialog, the PrintPage event is raised again, sending the output to the printer instead of the preview dialog. This is why the string is reset at the end of the rendering process in step 3.

The following code example shows the Click event-handling method for a button on the form. This event-handling method calls the methods to read the document and show the print preview dialog.

private void printPreviewButton_Click(object sender, EventArgs e)
{
printPreviewDialog1.Document = printDocument1;
printPreviewDialog1.ShowDialog();

}

Private Sub printPreviewButton_Click(ByVal sender As Object, _
ByVal e As EventArgs) Handles printPreviewButton.Click

printPreviewDialog1.Document = printDocument1
printPreviewDialog1.ShowDialog()
End Sub


## Example

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);
printDocument1.PrintPage +=
new PrintPageEventHandler(printDocument1_PrintPage);
}
{
string docName = "testPage.txt";
string docPath = @"c:\";
printDocument1.DocumentName = docName;
using (FileStream stream = new FileStream(docPath + docName, FileMode.Open))
{
}
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)
{
printPreviewDialog1.Document = printDocument1;
printPreviewDialog1.ShowDialog();

}

static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new Form1());
}
}
}

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)

End Sub

Dim docName As String = "testPage.txt"
Dim docPath As String = "c:\"
printDocument1.DocumentName = docName
Dim stream As New FileStream(docPath + docName, FileMode.Open)
Try
Try
Finally
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

printPreviewDialog1.Document = printDocument1
printPreviewDialog1.ShowDialog()
End Sub

Shared Sub Main()
Application.EnableVisualStyles()
Application.SetCompatibleTextRenderingDefault(False)
Application.Run(New Form1())

End Sub
End Class


## Compiling the Code

This example requires:

• References to the System, System.Windows.Forms, System.Drawing assemblies.