Question

So here is my situation: First of all, all of my printing code is stored in a module, which is called when I click the print button. My problem is, my pages print fine the first time I print my document, but if I click print again, the pages start printing on top of one another. When I debug, e.hasmorepages will be set to false, but it loops around and runs the print_page event again a couple times... I'm confused why it loops several times even though hasmorepages is definitely set to false?? The fact that usually prints right the first time but not the second time I click print makes the think something needs to be disposed. I know my page number variable is set to 1 before each print so it isn't that. The code I am using used to work until I moved it to it's own module.

Note: When I click print, i choose if I want a delivery recipt. if no, a store copy and customer copy are printed. If yes then Store, customer, and delivery copy are printed. Usually the Store and customer copy are printed on top of one another but the delivery copy is correct, so 2 pages are printed instead of 3.

Here is the basic outline of my module:

Imports System.Drawing
Imports System.Drawing.Printing

Module Receipt2
Public copy As Integer
Dim row As Integer

Dim ItemsRowCount As Integer = Invoice.dgvInvoiceItems.RowCount
Private Doc As New PrintDocument()

Public Sub printInvoice()

    Try
        copy = 1

        AddHandler Doc.PrintPage, AddressOf Print_PrintPage
        Doc.Print()
        row = 0
        Doc.Dispose()

        copy = 1

    Catch ex As Exception
        MessageBox.Show(ex.Message)
    End Try
End Sub

Private Sub Print_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs)


    Try

        'RECEIPT ITEMS PRINTED HERE


        'print Store/customer copy and sig line
        If copy = 1 Then
            g.DrawString("Store Copy", New Font("Verdana", 15, FontStyle.Italic), Brushes.DarkRed, 50, 1045)


            e.HasMorePages = True
            copy = copy + 1
            row = 0
            Exit Sub
        ElseIf copy = 2 Then
            g.DrawString("Customer Copy", New Font("Verdana", 15, FontStyle.Italic), Brushes.DarkRed, 50, 1045)


            If Invoice.boolDeliveryReceipt = True Then
                e.HasMorePages = True
                copy = copy + 1
                row = 0
                Exit Sub
            End If

        ElseIf copy = 3 Then
            g.DrawString("Delivery Copy", New Font("Verdana", 15, FontStyle.Italic), Brushes.DarkRed, 50, 1045)


        End If


        'e.HasMorePages = False

    Catch ex As Exception

        MessageBox.Show(ex.Message)

    End Try
End Sub
End Module

Thanks so much for taking the time to look this over! I've spent hours trying to track the problem down and just not having any luck.

Was it helpful?

Solution

 Private Doc As New PrintDocument()

This is where the problem started.

    AddHandler Doc.PrintPage, AddressOf Print_PrintPage

This is where you nailed yourself. The As New syntax is pretty handy, but it will create an object just once. Problem is, only the first call to printInvoice creates the PrintDocument object. But every time you call printInvoice(), you add another PrintPage event handler to the same object. The net effect is that the second time you print, your PrintPage event handler will run twice for each page. The third time it will run three times. Etcetera. The Dispose() method doesn't otherwise do anything, a PrintDocument doesn't use disposable resources. Setting it to Nothing would fix the problem.

You fix this by just creating a new PrintDocument object every time you print. So

Private Doc As PrintDocument

Public Sub printInvoice()

    Try
        copy = 1

        Doc = new PrintDocument()
        AddHandler Doc.PrintPage, AddressOf Print_PrintPage
        ItemsRowCount = Invoice.dgvInvoiceItems.RowCount
        Doc.Print()
        '' etc...

Further improve this code by making "Doc" a local variable. Or moving the code into a class.

Note how your ItemsRowCount variable has the same problem. It might be initialized too early, storing the wrong row count. And if you print again, later, with a different invoice then you'll definitely get the wrong number of rows.

Be careful with global variables, they have a knack for causing problems like this.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top