VB.NET Printing For Dummies

In order to send stuff to the printer in VB.NET, it is not quite as simple as dealing with the Printer object as in VB6. There are a couple of extra steps involved. Here is what I found, along with some helper methods that you might find useful.

On the form you want to print from, pull up the Toolbox and add a PrintDocument, a PrintDialog, and a Button, set the Document property of the PrintDialog to point to the PrintDocument you just created, and in the button’s Click event, insert the following code:

    Private Sub butPrint_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles butPrint.Click
 
        If PrintDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then
            PrintDocument1.DefaultPageSettings.Landscape = True
            PrintDocument1.Print()
        End If
 
    End Sub
 
    Private Sub PrintDocument1_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
 
        PrintTestPage(e.Graphics, PrintDocument1)
 
    End Sub

The Print method call in the button click event then fires the PrintDocument PrintPage event. Notice that I have set the default page settings to landscape. Don’t forget to wire the PrintDialog Document property to your PrintDocument, otherwise if you change the printer to print to in the print dialog, the document will still go to the default printer.

The PrintTestPage method is just something simple that I put together to make sure that the coordinates and justifications are all working fine. Here is that code:

    Sub PrintTestPage(ByVal g As System.Drawing.Graphics, ByVal doc As PrintDocument)
 
        Dim x, y As Integer
 
        For x = 0 To 100 Step 10
            For y = 0 To 100 Step 10
                PrintAtLocationWithColor(g, doc, x.ToString + ", " + y.ToString, x, y, _
                                         If(x = 0, "L", If(x = 100, "R", "C")), If(y = 0, "T", If(y = 100, "B", "C")), _
                                         "Arial", 8, True, Brushes.Red)
            Next
        Next
 
        PrintRectangle(g, doc, 0, 0, 100, 100)
        PrintRectangle(g, doc, 10, 10, 80, 80)
        PrintRectangle(g, doc, 20, 20, 60, 60)
        PrintRectangle(g, doc, 30, 30, 40, 40)
        PrintRectangle(g, doc, 40, 40, 20, 20)
 
    End Sub

The two methods called here, PrintAtLocationWithColor and PrintRectangle, are shown here:

    Sub PrintAtLocationWithColor(ByVal pg As Graphics, ByVal pd As PrintDocument, ByVal s As String, _
                                ByVal xPosition As Single, ByVal yPosition As Single, _
                                ByVal justification As String, ByVal verticalJustification As String, _
                                ByVal fontFace As String, ByVal fontSize As Single, _
                                ByVal fontBold As Boolean, ByVal theColor As Brush)
 
        Dim w, h As Single
        Dim x, y As Single
        Dim f As Font
        Dim sty As FontStyle
 
        sty = FontStyle.Regular
        If fontBold Then sty = sty + FontStyle.Bold
        If fontSize < 1 Then fontSize = 8.0
        f = New Font(fontFace, fontSize, sty)
 
        If pd.DefaultPageSettings.Landscape Then
            x = xPosition / 100 * (pd.DefaultPageSettings.PrintableArea.Height)
            y = yPosition / 100 * (pd.DefaultPageSettings.PrintableArea.Width)
        Else
            x = xPosition / 100 * (pd.DefaultPageSettings.PrintableArea.Width)
            y = yPosition / 100 * (pd.DefaultPageSettings.PrintableArea.Height)
        End If
 
        w = pg.MeasureString(s, f).Width
        h = pg.MeasureString(s, f).Height
 
        If Left(UCase(justification), 1) = "C" Then
            x = x - w / 2
        End If
        If Left(UCase(justification), 1) = "R" Then
            x = x - w
        End If
 
        If Left(UCase(verticalJustification), 1) = "C" Then
            y = y - h / 2
        End If
        If Left(UCase(verticalJustification), 1) = "B" Then
            y = y - h
        End If
 
        pg.DrawString(s, f, theColor, x, y)
 
    End Sub
 
    Sub PrintRectangle(ByVal pg As Graphics, ByVal pd As PrintDocument, ByVal xPosition As Single, ByVal yPosition As Single, _
                                ByVal width As Single, ByVal height As Single)
 
        Dim w, h As Single
        Dim x, y As Single
 
        If pd.DefaultPageSettings.Landscape Then
            x = xPosition / 100 * (pd.DefaultPageSettings.PrintableArea.Height)
            y = yPosition / 100 * (pd.DefaultPageSettings.PrintableArea.Width)
            w = width / 100 * (pd.DefaultPageSettings.PrintableArea.Height)
            h = height / 100 * (pd.DefaultPageSettings.PrintableArea.Width)
        Else
            x = xPosition / 100 * (pd.DefaultPageSettings.PrintableArea.Width)
            y = yPosition / 100 * (pd.DefaultPageSettings.PrintableArea.Height)
            w = width / 100 * (pd.DefaultPageSettings.PrintableArea.Width)
            h = height / 100 * (pd.DefaultPageSettings.PrintableArea.Height)
        End If
 
        pg.DrawRectangle(Pens.Black, x, y, w, h)
 
    End Sub

All of the positioning and size parameters of these methods are percentages across and down the page, which I find much easier to deal with than absolute or printer specific positioning. This makes it dead simple to scale the reports to any page size I want to use.

Leave a Reply