Stefan
Stefan

Reputation: 1433

Using PrintDocument to print multiple pages

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

Answers (2)

Dour High Arch
Dour High Arch

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 floats for coordinates, do not convert between ints.

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

LarsTech
LarsTech

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

Related Questions