HasMorePages = HasMoreProblems

brix_zx2

Member
Joined
Apr 6, 2005
Messages
12
Location
Altus AFB
Programming Experience
1-3
This is going to be extremely summarized because I have everything else right, but I'm thinking that I have the hasmorepages property set in the wrong spot. Hopefully someone will know how I can arrange this to work right. It won't print new pages but it will print one page and at the start of a new page it prints over the first page.

So my code is something like this:

Do Until varEnd = True

ev.Graphics.Drawstring (.....Print My Lines.....)

myCurrencyManager.....Move to the next record......

ev.Graphics.Drawstring (.....Print some more lines......)

If LastRecord Then
varEnd = True
Else
ev.HasMorePages = True
myCurrencyManager.....Move to the next record......
End If

Loop
 
The only point at which the value of the HasMorePages property of the PrintPageEventArgs object matters is when the PrintDocument.PrintPage event handler exits. If HasMorePages is True, the PrintPage event will fire again. If HasMorePages is False, it will not. You need to use variables external to the PrintPage event handler to keep track of what needs to be printed. Let's say you have an Array of Strings, and you want to print them 10 to a page. Your code would look something like this:
VB.NET:
Dim printIndex As Integer = 0

Private Sub PrintDocument1_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
	For i As Integer = 0 to 9
		If printIndex > stringArray.Length - 1 Then
			'There are no more Strings to print.
			e.HasMorePages = False

			'Reset the print index for the next print run.
			printIndex = 0

			Exit Sub
		End If

		'Print the String at stringArray(printIndex) at the required position.

		printIndex +=1
	Next

	'There may or may not be more pages to print.
	e.HasMorePages = printIndex < stringArray.Length
End Sub
 
Last edited:
I think I understand what you are saying... I have a Sub Print_Click that contains

Dim evPrint As PrintPageEventArgs
AddHandler PrintDoc.PrintPage, AddressOf Me.PrintText
PrintDoc.Print()

Then my Sub PrintText goes through and does my DrawStrings. And that is also where my HasMorePages Property is set. That's not working. I've also tried putting it in the Print_Click sub, but I didn't get that to work correctly.
 
You don't have to declare a variable of type PrintPageEventArgs. You'll notice in my code that the second argument to an event handler for the PrintDocument.PrintPage event is of type PrintPageEventArgs. This is generated automatically and passed to the event handler when the event fires. If you have added your PrintDocument to a Form in the designer, double-clicking it will automatically generate a PrintPage event handler for you.

Your Print_Click procedure, which I assume is a Click event handler for a Button, shouldn't know anything about the PrintPageEventArgs object or its HasMorePages property. When you call PrintDoc.Print, the PrintPage event fires and your PrintText procedure is called. Once PrintText completes, if the HasMorePages property of its second argument, which is a PrintPageEventArgs object, is True then the PrintPage event will fire again and PrintText will be called again. Each time PrintText is called, there must be some external, i.e. form-level, variable(s) it can access that tell it where it is up to in the print process. This process will continue until at some point the PrintText procedure completes and the HasMorePages property of its second argument is False. The HasMorePages property of the PrintPageEventArgs object passed to the PrintPage event handler is set to False by default, so it is up to you to set it to True if there are more pages to print.
 
If you would like a working example, here's an excerpt of some code of mine, which is part of a released product, that prints an unknown number of multiple pages. It takes the checked items from a ListView, formats them and prints them three to a page.
VB.NET:
	Private printIndex As Integer 'The index of the listview item being printed.
	Private majorFont As New Font("Arial", 10, FontStyle.Regular, GraphicsUnit.Point) 'The font used to print large text.
	Private minorFont As New Font("Arial", 7, FontStyle.Regular, GraphicsUnit.Point) 'The font used to print small text.

'...

	Private Sub printButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles printButton.Click
		'Reset the print index.
		Me.printIndex = 0

		If Me.printDialogue.ShowDialog() = DialogResult.OK Then
#If DEBUG Then
			'Display a print preview.
		    Me.printPreviewDialogue.WindowState = FormWindowState.Maximized
			Me.printPreviewDialogue.ShowDialog()
#Else
			'Print the mail-outs directly.
			Me.printDocument.Print()
#End If
		End If
	End Sub

	Private Sub printDocument_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles printDocument.PrintPage
		Dim customerItem As ListViewItem
		Dim customerName, customerAddress As String

		'Print three customers per page.
		For i As Integer = 0 To 2
			If Me.printIndex >= Me.vipListView.CheckedItems.Count Then
			    'Reset the print index in case this was a preview.
				Me.printIndex = 0

				e.HasMorePages = False
				Exit For
			End If

			customerItem = Me.vipListView.CheckedItems(Me.printIndex)

			'Build the customer name starting with the salutation.
			customerName = customerItem.SubItems(3).Text
			If customerItem.SubItems(4).Text <> "" Then
				If customerName <> "" Then
				    customerName += " "
				End If

				'Add the given names.
			    customerName += customerItem.SubItems(4).Text
			End If
			If customerItem.SubItems(5).Text <> "" Then
				If customerName <> "" Then
				    customerName += " "
				End If

				'Add the surname.
			    customerName += customerItem.SubItems(5).Text
			End If

		    'Build the customer address starting with the number and street.
		    customerAddress = customerItem.SubItems(6).Text.Replace(",", vbNewLine)
			If customerItem.SubItems(7).Text <> "" Then
				If customerAddress <> "" Then
				    customerAddress += vbNewLine
				End If

				'Add the suburb.
			    customerAddress += customerItem.SubItems(7).Text
			End If
			If customerItem.SubItems(8).Text <> "" Then
				If customerAddress <> "" Then
				    customerAddress += vbNewLine
				End If

				'Add the state.
			    customerAddress += customerItem.SubItems(8).Text

			    If customerItem.SubItems(9).Text <> "" Then
				 If customerAddress <> "" Then
					 customerAddress += ", "
					End If

				    'Add the postcode.
				 customerAddress += customerItem.SubItems(9).Text
				End If
			Else
			    If customerItem.SubItems(9).Text <> "" Then
				 If customerAddress <> "" Then
					 customerAddress += vbNewLine
					End If

				    'Add the postcode.
				 customerAddress += customerItem.SubItems(9).Text
				End If
			End If
			If customerItem.SubItems(10).Text <> "" Then
				If customerAddress <> "" Then
				    customerAddress += vbNewLine
				End If

				'Add the country.
			    customerAddress += customerItem.SubItems(10).Text
			End If

		 e.Graphics.DrawString(String.Format("{0}{1}{2}", customerName, vbNewLine, customerAddress), Me.majorFont, Brushes.Black, 130, i * 390 + 240)

			Dim vipPointsCount As Integer = Integer.Parse(customerItem.SubItems(2).Text)

			If vipPointsCount > 0 Then
			 e.Graphics.DrawString(String.Format("Dear Customer,{0}As at {1} you have accumulated VIP points to the value of {2},{0}which can be redeemed on any items currently in stock.{0}Please read the conditions of use relating to VIP points.", _
												 vbNewLine, _
												 Date.Today.ToShortDateString(), _
												 FormatCurrency(vipPointsCount * Globals.Options.PointsRedeemedValue, 0)), _
									 Me.majorFont, _
									 Brushes.Black, _
									 130, _
									 i * 390 + 110)
			    e.Graphics.DrawString(Me.CONDITIONSOFUSE, _
									 Me.minorFont, _
									 Brushes.Black, _
									 500, _
									 i * 390 + 190)
			End If

			e.HasMorePages = True
			Me.printIndex += 1
		Next
	End Sub
 
Hey thanks for the help I ended up figuring it out. For some reason if I set the property inside a loop it would work but once I put it outside the loop it worked fine. I don't quite understand the why on that. But I'm not going to question it. Thanks again.
 
Back
Top