所以这是我的情况:首先,我的所有打印代码都存储在一个模块中,当我单击打印按钮时会调用该模块。我的问题是,我的页面在我第一次打印文档时打印正常,但是如果我再次单击打印,页面就会开始相互打印。当我调试时,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
非常感谢您花时间来看看这个!我花了好几个小时试图追踪问题并且没有任何运气。
答案 0 :(得分: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变量具有相同的问题。它可能太早初始化,存储错误的行数。如果您再次使用不同的发票打印,那么您肯定会得到错误的行数。
小心全局变量,它们有引发这样的问题的诀窍。