PrintDocument_PrintPage goes into endless loop until e.HasMorePages=False

  • Thread starter Thread starter moti
  • Start date Start date
M

moti

Whenever I use PrintDocument.Print() to print a page it goes to
PrintDocument_PrintPage and stays there forever unless I set
e.HasMorePages to False.
When I set it to False it prints the page but is closes the print
file. The effect is that it prints all my pages but creates a print
job for each page. So if I print 100 pages I get 100 print jobs.
The only way I went around this was to put all my page-filling code
within PrintDocument_PrintPage.
Is there a way around this?
 
moti said:
Whenever I use PrintDocument.Print() to print a page it goes to
PrintDocument_PrintPage and stays there forever unless I set
e.HasMorePages to False. Normal
When I set it to False it prints the page but is closes the print
file.
Don't open the file in the PrintPage event - open it in a different
sub then let the PrintPage sub get called from there.
then it won't close the file.
The effect is that it prints all my pages but creates a print
job for each page. So if I print 100 pages I get 100 print jobs.
The only way I went around this was to put all my page-filling code
within PrintDocument_PrintPage.
Is there a way around this?
Since the PrintPage event get called over and over until HasMorePages is
false, you may want to use module-level variables to keep track of which
page you're on and which line you're on.
 
Thank you for replying.
Originally I had all my code outside PrintPage. I had a module
variable called MorePages and did a PrintDocument.Print() to print the
page when it was full. What it does is go to the
PrintDocument_PrintPage, where I set e.HasMorePages to MorePages. But
it never gets out of PrintDocument_PrintPage until
e.HasMorePages=False. If I set it to False then it does get out of
PrintDocument_PrintPage and closes the print file, which creates every
page as a separate file. The only way around this was to put all my
print logic in PrintDocument_PrintPage.
The following code was my original code that did not work:

Private Sub icoPrintAll_Click(ByVal sender As System.Object, ByVal
e As System.EventArgs) Handles icoPrintAll.Click
'Dim FirstPage As Boolean = True
'MorePages = True
'For I = 0 To DetRowCount - 1
' s = dedv.Table.Rows.Item(I).Item(15).ToString
' If File.Exists(tbDocPath.Text + "\" + s) And InStrRev(s,
".") = 0 Then
' PictureDet.Image = Image.FromFile(tbDocPath.Text +
"\" + s)
' m_PrintBitmap = CType(PictureDet.Image, Bitmap)
' m_PrintDocument = New PrintDocument
' m_PrintBitmap.SetResolution(200, 200)
' If I = DetRowCount - 1 Then MorePages = False
' PrintDialog1.Document = m_PrintDocument
' If FirstPage Then FirstPage = False : If Not
(PrintDialog1.ShowDialog = System.Windows.Forms.DialogResult.OK) Then
Exit Sub
' m_PrintDocument.Print()
' End If
'Next
'MorePages = False
'm_PrintDocument.Print()
End Sub

' Print the form image.
Private Sub m_PrintDocument_PrintPage(ByVal sender As Object,
ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles
m_PrintDocument.PrintPage
e.Graphics.DrawImage(m_PrintBitmap, 0, 0)
If MorePages = False Then
e.HasMorePages = False
Else
e.HasMorePages = True
End If
End Sub
 
moti said:
Thank you for replying.
Originally I had all my code outside PrintPage. I had a module
variable called MorePages and did a PrintDocument.Print() to print the
page when it was full. What it does is go to the
PrintDocument_PrintPage, where I set e.HasMorePages to MorePages. But
it never gets out of PrintDocument_PrintPage until
e.HasMorePages=False. If I set it to False then it does get out of
PrintDocument_PrintPage and closes the print file, which creates every
page as a separate file. The only way around this was to put all my
print logic in PrintDocument_PrintPage.
The following code was my original code that did not work:

Private Sub icoPrintAll_Click(ByVal sender As System.Object, ByVal
e As System.EventArgs) Handles icoPrintAll.Click
'Dim FirstPage As Boolean = True
'MorePages = True
'For I = 0 To DetRowCount - 1
' s = dedv.Table.Rows.Item(I).Item(15).ToString
' If File.Exists(tbDocPath.Text + "\" + s) And InStrRev(s,
".") = 0 Then
' PictureDet.Image = Image.FromFile(tbDocPath.Text +
"\" + s)
' m_PrintBitmap = CType(PictureDet.Image, Bitmap)
' m_PrintDocument = New PrintDocument
' m_PrintBitmap.SetResolution(200, 200)
' If I = DetRowCount - 1 Then MorePages = False
' PrintDialog1.Document = m_PrintDocument
' If FirstPage Then FirstPage = False : If Not
(PrintDialog1.ShowDialog = System.Windows.Forms.DialogResult.OK) Then
Exit Sub
' m_PrintDocument.Print()
' End If
'Next
'MorePages = False
'm_PrintDocument.Print()
End Sub

' Print the form image.
Private Sub m_PrintDocument_PrintPage(ByVal sender As Object,
ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles
m_PrintDocument.PrintPage
e.Graphics.DrawImage(m_PrintBitmap, 0, 0)
If MorePages = False Then
e.HasMorePages = False
Else
e.HasMorePages = True
End If
End Sub

Keep in mind that the variables you declare in the icoPrintAll_Click sub
only live in that sub - and those variables cannot be used by the PrintPage
sub - or any other sub. Like I said before - keep in mind that the PrintPage
sub will be called over and over until e.HasMorePages is false, so any
variables you need to keep track of page numbers, line numbers, etc need to
be declared at the top of the module (not the sub) so they won't be
re-initialized on every execution of the PrintPage sub.
here's a tutorial on using the PrintPage eventhandler:
http://www.vbdotnetheaven.com/Uploa...rticleID=b89f0348-fc61-4c30-9151-97cb0652a8c1
 
Thank you again.
I looked at the link but noticed it had all its logic within
PrintDocument_PrintPage too. Is there any way to get the code out of
it? Otherwise, for each type of list another PrintDocument_PrintPage
sub has to be created (with a dif name) and again all its logic (data
gathering) must be within it or else I have to create an array of
pages (and if the list is 1000 pages?). There has to be another way or
else I must be doing somthing wrong. Could it be that my print is
printing graphic pages? I looked all over and the dif code for
text/image is mostly the same except that text is internally converted
to graphics.
Anyway, thanks for the help and if you can show me any type of VB code
that prints, with its print logic outside of PrintDocument_PrintPage,
it would really be appreciated. As is, I can't even class it because
it still won't get out of PrintDocument_PrintPage without
e.MorePages=False.
 
moti said:
Thank you again.
I looked at the link but noticed it had all its logic within
PrintDocument_PrintPage too. Is there any way to get the code out of
it? Otherwise, for each type of list another PrintDocument_PrintPage
sub has to be created (with a dif name) and again all its logic (data
gathering) must be within it or else I have to create an array of
pages (and if the list is 1000 pages?). There has to be another way or
else I must be doing somthing wrong. Could it be that my print is
printing graphic pages? I looked all over and the dif code for
text/image is mostly the same except that text is internally converted
to graphics.
Anyway, thanks for the help and if you can show me any type of VB code
that prints, with its print logic outside of PrintDocument_PrintPage,
it would really be appreciated. As is, I can't even class it because
it still won't get out of PrintDocument_PrintPage without
e.MorePages=False.

You're gonna have a long wait, because until e.HasMorePages = false, the
PrintDocument_PrintPage event will continually continuously over and over
again will repeatedly be called over and over and over.
That is how it works.
Inside the PrintDocument_PrintPage sub, you need to have an if statement
If (everything I want to print has been printed) Then
e.HasMorePages = false
End If

If you don't know how to tell when everything you want to print has been
printed, then maybe Printing isn't the big problem.
 
Moti,
Whenever I use PrintDocument.Print() to print a page it goes to
PrintDocument_PrintPage and stays there forever unless I set
e.HasMorePages to False.
Ah! There's the rub!

PrintDocument.Print is used to print the entire "document", where "document"
is a print job. A "document" (aka print job) contains many pages.

PrintDocument_PrintPage prints one of the possibly many pages that the
document (aka print job) may contain.

As Hal has been trying to state: You need to change your vb code, and
possibly your thinking, such that when you call PrintDocument.Print you are
prepared for PrintDocument_PrintPage being called multiple times. You should
only need to call PrintDocument.Print one time for the entire document (aka
print job)!
So if I print 100 pages I get 100 print jobs.
The only way I went around this was to put all my page-filling code
within PrintDocument_PrintPage.
If you have a 100 page document that you want to print via PrintDocument,
your PrintDocument_PrintPage routine need to be prepared to be called 100
times! When you print this 100 page document; you will call
PrintDocument.Print once. PrintDocument.Print will then call
PrintDocument_PrintPage 100 times. On the 100th time you need to set
e.HasMorePages = False.

PrintDocument_PrintPage uses a class/module level field to keep track of
which page its on. Each time it is called it "increments" this class/module
level field to know which page it is printing. The PrintDocument_BeginPrint
event can be used before any pages are printed; for example to set the
class/module level field such that the first page is printed or to allocate
any resources such as pens, brushes, and fonts used during printing. The
PrintDocument.EndPrint event can be used after all the pages are printed;
for example to release any resources such as pens, brushes, and fonts used
during printing.
 
Back
Top