【问题标题】:vb.net printing error: print_printpage continues to loop even though e.hasmorepages = falsevb.net 打印错误:即使 e.hasmorepages = false,print_printpage 也会继续循环
【发布时间】:2013-05-07 15:30:41
【问题描述】:

所以这是我的情况:首先,我所有的打印代码都存储在一个模块中,当我单击打印按钮时会调用该模块。我的问题是,我的页面在我第一次打印文档时打印得很好,但是如果我再次单击打印,页面就会开始打印在另一个之上。当我调试时,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

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

【问题讨论】:

    标签: vb.net printing printdocument


    【解决方案1】:
     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 变量如何存在相同的问题。它可能初始化得太早,存储了 错误 行数。如果您稍后再次打印,使用不同的发票,那么您肯定会得到错误的行数。

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

    【讨论】:

    • 汉斯,我感激不尽!您创建新 PrintDocument 的建议解决了我的问题。不仅如此,果然我注意到下一张发票上的发票号码有问题,所以也感谢你的洞察力。感谢您花时间理顺我,非常感谢!
    猜你喜欢
    • 2017-03-29
    • 2020-08-19
    • 1970-01-01
    • 2021-03-20
    • 1970-01-01
    • 1970-01-01
    • 2021-02-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多