Reputation: 1433
I'm trying to print invoices. Invoices should be able to be printed on multiple pages, but that's where the problem kicks in. I can perfectly print an invoice on a single page, but as soon as the invoice doesn't fit on a single page, the printjob just quits on the first page.
Here's the code I'm using. 'artikelen' is a list of articles (List). I have read several similar examples, and I'm fairly sure I'm missing something here.
(Edited: some unneccesary code deleted)
public void PrintA4Factuur()
{
p = new PrintDocument();
p.PrintPage +=
new PrintPageEventHandler(printPage);
printPreviewDialog.Document = p;
printPreviewDialog.ShowDialog();
}
void printPage(object sender1, PrintPageEventArgs e1)
{
Graphics g = e1.Graphics;
int yPos = 320;
float pageHeight = e1.MarginBounds.Height;
int artikelPosition = 0;
while (yPos + 100 < pageHeight
&& artikelPosition < this.artikelen.Count)
{
// Do stuff with articles (printing details in different rectangles
artikelPosition += 1;
yPos += 20;
}
if (artikelPosition < this.artikelen.Count)
{
e1.HasMorePages = true;
return;
}
else
{
e1.HasMorePages = false;
}
}
Upvotes: 3
Views: 19991
Reputation: 21711
Well, Lars pointed out the problem with resetting artikelPosition
to zero at the start of each page, but there are a few other problems with this code.
You should always use e1.MarginBounds
for coordinates, as margins can be changed by the user and p.DefaultPageSettings
will not include that.
Use font metrics like GetHeight(yourDeviceGraphPort)
, don't hard-code line heights.
Always use float
s for coordinates, do not convert between int
s.
Fonts are non-managed resources, you must Dispose
them when you are done with them. It is inefficient to create and dispose fonts repeatedly in a loop; construct it before calling PrintDocument.Print()
and dispose it after all pages have printed.
There is also a Black SolidBrush already defined in System.Drawing
.
Upvotes: 5
Reputation: 81610
I found your code to do the opposite: if it prints more than one page, it continues to print into infinity.
Try moving your index position variable outside of the PrintPage
event, because setting it back to zero just sets it to the beginning again:
int artikelPosition = 0;
Reset it when you start the printing:
public void PrintA4Factuur()
{
artikelPosition = 0
p = new PrintDocument();
p.PrintPage += printPage;
printPreviewDialog.Document = p;
printPreviewDialog.ShowDialog();
}
Then comment it out in your PrintPage routine:
void printPage(object sender1, PrintPageEventArgs e1)
{
Graphics g = e1.Graphics;
int yPos = 320;
float pageHeight = e1.MarginBounds.Height;
// int artikelPosition = 0;
// continue with code
}
Upvotes: 3