0

所以这是我的情况:首先,我所有的打印代码都存储在一个模块中,当我单击打印按钮时会调用该模块。我的问题是,我的页面在我第一次打印文档时打印得很好,但是如果我再次单击打印,页面就会开始打印在另一个之上。当我调试时,e.hasmorepages 将设置为 false,但它会循环并再次运行 print_page 事件几次......我很困惑为什么它会循环多次,即使 hasmorepages 肯定设置为 false?通常第一次打印正确但第二次点击打印时不会打印的事实使我认为需要处理一些东西。我知道我的页码变量在每次打印之前都设置为 1,所以不是这样。我使用的代码在我将它移到它自己的模块之前一直有效。

注意:当我点击打印时,我会选择是否需要收货单。如果不是,则打印商店副本和客户副本。如果是,则打印商店、客户和交货副本。通常商店和客户副本打印在彼此的顶部,但交付副本是正确的,因此打印 2 页而不是 3 页。

这是我的模块的基本大纲:

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

非常感谢您抽出宝贵时间查看此内容!我花了几个小时试图追查问题,但没有任何运气。

4

1 回答 1

0
 Private Doc As New PrintDocument()

这就是问题开始的地方。

    AddHandler Doc.PrintPage, AddressOf Print_PrintPage

这是你把自己钉牢的地方。语法非常方便,As New但它只会创建一次对象。问题是,只有第一次调用 printInvoice 会创建 PrintDocument 对象。但是每次调用 printInvoice() 时,都会向同一个对象添加另一个PrintPage 事件处理程序。最终效果是第二次打印时,您的 PrintPage 事件处理程序将为每个页面运行两次。第三次它将运行三次。等等。Dispose() 方法不做任何事情, PrintDocument 不使用一次性资源。将其设置为 Nothing 可以解决问题。

您只需在每次打印时创建一个新的 PrintDocument 对象即可解决此问题。所以

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...

通过使“Doc”成为局部变量来进一步改进此代码。或者将代码移动到一个类中。

请注意您的 ItemsRowCount 变量如何存在相同的问题。它可能初始化得太早,存储了错误的行数。如果您稍后再次打印,使用不同的发票,那么您肯定会得到错误的行数。

小心全局变量,它们有导致此类问题的诀窍。

于 2013-05-07T16:48:56.103 回答