Printing with Windows FormsImportant Printing Classes:
Building an Application that PrintsThe easiest way to understand how the printing classes fit together is to work through a simple example that prints the contents of a text file to a printer. Step 1: Print LogicThe first thing you need to do is to write your printing logic. You do this by handling events on a PrintDocument. When the PrintDocument.Print() method is called, the following events are raised:
The PrintPage event arguments type (PrintPageEventArgs) has a HasMorePages property. If this is set to true when your event handler returns, PrintDocument sets up a new page and raises the PrintPage event again. Therefore, the logic in your PrintPage event handler is basically the following:
In the simplest case, you can create a PrintDocument and handle the PrintPage event as part of the Form that contains the print request.
Public Class PrintingExample1
Inherits System.Windows.Forms.Form
....
private printFont As Font
private streamToPrint As StreamReader
Public Sub New ()
MyBase.New
InitializeComponent()
End Sub
'Event fired when the user presses the print button
Private Sub printButton_Click(sender As object, e As System.EventArgs)
Try
streamToPrint = new StreamReader ("PrintMe.Txt")
Try
printFont = new Font("Arial", 10)
Dim pd as PrintDocument = new PrintDocument() 'Assumes the default printer
AddHandler pd.PrintPage, AddressOf Me.pd_PrintPage
pd.Print()
Finally
streamToPrint.Close()
End Try
Catch ex As Exception
MessageBox.Show("An error occurred printing the file - " + ex.Message)
End Try
End Sub
'Event fired for each page to print
Private Sub pd_PrintPage(sender As object, ev As System.Drawing.Printing.PrintPageEventArgs)
Dim lpp As Single = 0
Dim yPos As Single = 0
Dim count As Integer = 0
Dim leftMargin As Single = ev.MarginBounds.Left
Dim topMargin As Single = ev.MarginBounds.Top
Dim line as String
'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
line=streamToPrint.ReadLine()
while (count < lpp AND line <> Nothing)
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 = count + 1
if (count < lpp) then
line=streamToPrint.ReadLine()
end if
End While
'If we have more lines then print another page
If (line <> Nothing) Then
ev.HasMorePages = True
Else
ev.HasMorePages = False
End If
End Sub
....
End Class
VB
To view and run this sample.
Step 2: Defining Your Own Print DocumentFor a complex print job, or a print logic that you wish to reuse across multiple forms, you can derive a new class from PrintDocument and encapsulate your printing logic in that class. In this case, you handle the PrintPage event by overriding the OnPrintPage method, rather than using an event handler.
Public Class TextFilePrintDocument
Inherits PrintDocument
Private printFont As Font
Private streamToPrint As StreamReader
Public Sub New(streamToPrint As StreamReader)
MyBase.New
Me.streamToPrint = streamToPrint
End Sub
'Override OnBeginPrint to set up the font we are going to use
Overrides Protected Sub OnBeginPrint(ev As PrintEventArgs)
MyBase.OnBeginPrint(ev)
printFont = new Font("Arial", 10)
End Sub
'Override the OnPrintPage to provide the printing logic for the document
Overrides Protected Sub OnPrintPage(ev As PrintPageEventArgs)
MyBase.OnPrintPage(ev)
Dim lpp As Single = 0
Dim yPos As Single = 0
Dim count As Integer = 0
Dim leftMargin As Single = ev.MarginBounds.Left
Dim topMargin As Single = ev.MarginBounds.Top
Dim line as String
'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
line = streamToPrint.ReadLine()
While (count < lpp And line <> Nothing)
yPos = topMargin + (count * printFont.GetHeight(ev.Graphics))
ev.Graphics.DrawString(line, printFont, Brushes.Black, leftMargin, _
yPos, New StringFormat())
count = count + 1
If (count < lpp) Then
line = streamToPrint.ReadLine()
End If
End While
'If we have more lines then print another page
If (line <> Nothing) Then
ev.HasMorePages = True
Else
ev.HasMorePages = False
End If
End Sub
End Class
VB
To view and run this sample.
Step 3: Allowing the User to Choose a PrinterWhen you have your print logic working, the next step is to allow the user to choose a printer with the Windows Print dialog. To do this, you create a PrintDocument and pass it to the PrintDialog.
Private Sub printButton_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Try
Dim streamToPrint As StreamReader = New StreamReader("PrintMe.Txt")
Try
'Assumes the default printer
Dim pd As TextFilePrintDocument = New TextFilePrintDocument(streamToPrint)
Dim dlg As New PrintDialog()
dlg.Document = pd
Dim result As DialogResult = dlg.ShowDialog()
If (result = System.Windows.Forms.DialogResult.OK) Then
pd.Print()
End If
Finally
streamToPrint.Close()
End Try
Catch ex As Exception
MessageBox.Show("An error occurred printing the file - " + ex.Message)
End Try
End Sub
VB
To view and run this sample.
Step 4: Allowing the User to Choose Page SettingsOnce the user can choose a printer and print a document, you can allow them to choose page settings, such as the orientation of the paper or the size of the margins. To do this, you create a PageSettings instance and pass it to the PageSetupDialog.
'Event fired when the user presses the page setup button
Private Sub pageSetupButton_Click(sender As object, e As System.EventArgs)
Try
Dim psDlg As New PageSetupDialog
If (storedPageSettings Is Nothing) Then
storedPageSettings = new PageSettings()
End If
psDlg.PageSettings = storedPageSettings
psDlg.ShowDialog
Catch ex As Exception
MessageBox.Show("An error occurred - " + ex.Message)
End Try
End Sub
VB
You can then use this custom PageSettings instance when the user prints the document.
'Event fired when the user presses the print button
Private Sub printButton_Click(sender As object, e As System.EventArgs)
Try
Dim streamToPrint As StreamReader = new StreamReader ("PrintMe.Txt")
Try
'Assumes the default printer
Dim pd As TextFilePrintDocument = new TextFilePrintDocument(streamToPrint)
If Not (storedPageSettings Is Nothing) Then
pd.DefaultPageSettings = storedPageSettings
End If
Dim dlg As New PrintDialog()
dlg.Document = pd
Dim result As DialogResult = dlg.ShowDialog()
If (result = System.Windows.Forms.DialogResult.OK) Then
pd.Print()
End If
Finally
streamToPrint.Close()
End Try
Catch ex As Exception
MessageBox.Show("An error occurred printing the file - " + ex.Message)
End Try
End Sub
VB
To view and run this sample.
The Print Preview window allows a user to preview their document before printing it. You can add
a Print Preview window to your application by creating a PrintDocument and passing it to the PrintPreview dialog.
To view and run this sample.
The Windows Forms samples include a sample called SimplePad that shows how to build a simple
text editor that prints the file that is being edited.
|