coolhand
coolhand

Reputation: 2061

vb.NET: Printing Multiple Pages

I'm failing at signaling my printer to start a new page. It continues to print on page 1 after I set e.HasMorePages = True. With my font, I can cleanly print ~ 30 lines per page and still maintain the border

    'print the text
    'create a string array from the listView equipment items
    Dim equip() As classReportObj
    ReDim equip(0 To lstReport.Items.Count - 1)
    For i = 0 To lstReport.Items.Count - 1
        equip(i) =
            New classReportObj() With {.name = lstReport.Items(i).Text, .type = lstReport.Items(i).SubItems(1).Text,
                                       .completeTests = lstReport.Items(i).SubItems(2).Text, .incompleteTests = lstReport.Items(i).SubItems(3).Text,
                                       .status = lstReport.Items(i).SubItems(4).Text}
    Next i

    'get the coordinates for the first row and the columns
    Dim y As Integer = e.MarginBounds.Top
    Dim x0 As Integer = e.MarginBounds.Left
    Dim x1 As Integer = x0 + 150
    Dim x2 As Integer = x1 + 150
    Dim x3 As Integer = x2 + 150
    Dim x4 As Integer = x3 + 120
    Dim headerFont As New Font("Times New Roman", 10)
    Dim maxLines As Integer 'maximum number of lines per page
    maxLines = 30 '30 lines per page, including headers
    Dim lineCount As Integer 'counts lines per printed page

    'make a new font to use
    Using theFont As New Font("Times New Roman", 10)
        'draw the column headers
        e.Graphics.DrawString("Project: " & project.name & " " & thisReportType & " Report, " & Now, theFont, Brushes.Black, x0, y)
        e.Graphics.DrawString("Name", headerFont, Brushes.Black, x0, y + 30)
        e.Graphics.DrawString("Type", headerFont, Brushes.Black, x1, y + 30)
        e.Graphics.DrawString("Complete Tests", headerFont, Brushes.Black, x2, y + 30)
        e.Graphics.DrawString("Incomplete Tests", headerFont, Brushes.Black, x3, y + 30)
        e.Graphics.DrawString("Status", headerFont, Brushes.Black, x4, y + 30)

        'mmove Y down for the next row
        y += 60

        Dim nameMax As Integer 'max characters for name
        Dim typeMax As Integer 'max characters for type
        'loop through each equipment to display the data
        For Each aEquip In equip

            'set the max character length for name and type
            If aEquip.name.Length < 23 Then
                nameMax = aEquip.name.Length
            Else
                nameMax = 23
            End If
            '
            If aEquip.type.Length < 23 Then
                typeMax = aEquip.type.Length
            Else
                typeMax = 23
            End If

            'display the equipment values
            e.Graphics.DrawString(aEquip.name.Substring(0, nameMax), theFont, Brushes.Black, x0, y)
            e.Graphics.DrawString(aEquip.type.Substring(0, typeMax), theFont, Brushes.Black, x1, y)
            e.Graphics.DrawString(aEquip.completeTests, theFont, Brushes.Black, x2, y)
            e.Graphics.DrawString(aEquip.incompleteTests, theFont, Brushes.Black, x3, y)
            e.Graphics.DrawString(aEquip.status, theFont, Brushes.Black, x4, y)
            'move Y down for the next row
            y += 30

            'increment the line counter for each piece of equipment
            lineCount = lineCount + 1
            'if we've reached the maximum number of lines per page
            If (lineCount Mod maxLines) = 0 Then
                'draw a box around it all
                e.Graphics.DrawRectangle(Pens.Black, x0, e.MarginBounds.Top + 30, x4 - x0 + 100, y - e.MarginBounds.Top - 30)
                e.HasMorePages = True 'But it doesn't start a new page, it continues printing page 1 unless I exit
            Else
                e.HasMorePages = False
            End If
        Next
    End Using

    'draw a box around it all
    e.Graphics.DrawRectangle(Pens.Black, x0, e.MarginBounds.Top + 30, x4 - x0 + 100, y - e.MarginBounds.Top - 30)
    'only printing one page (for now)
    e.HasMorePages = False
End Sub

Upvotes: 0

Views: 2976

Answers (1)

jmcilhinney
jmcilhinney

Reputation: 54477

You seem not to understand what e.HasMorePages actually does. All it does is cause the PrintPage event to be raised again. If all your PrintPage event handler does is print the first page then that's all you see printed over and over.

The PrintPage event handler is supposed to print one page. The very first thing you would usually do in that event handler is determine what page needs to be printed. That is generally going to require that you keep some sort of count OUTSIDE the event handler.

That count might be specifically how many pages have been printed or it might be an index into a list of records or something else. Whatever it is, it needs to tell you insider the PrintPage event handler how to get what needs to be printed on the current page.

Here's an example that will print a list of Strings, five to a page:

Private lines As New List(Of String)
Private overallRecordIndex As Integer
Private pageNumber As Integer

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    overallRecordIndex = 0
    pageNumber = 1
    PrintDocument1.Print()
End Sub

Private Sub PrintDocument1_PrintPage(sender As Object, e As Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
    Dim pageRecordIndex = 0
    Dim yOffset = 10

    Do While pageRecordIndex < 5 AndAlso overallRecordIndex < lines.Count
        e.Graphics.DrawString(String.Format("Page {0}, Record {1}: {2}",
                                            pageNumber,
                                            overallRecordIndex,
                                            lines(overallRecordIndex)),
                              Me.Font,
                              Brushes.Black,
                              10,
                              yOffset)

        overallRecordIndex += 1
        pageRecordIndex += 1
        yOffset += 20
    Loop

    e.HasMorePages = (overallRecordIndex < lines.Count)

    If e.HasMorePages Then
        pageNumber += 1
    End If
End Sub

Upvotes: 5

Related Questions