I am working on a function in my C# WinForms application that lets me print warehouse pick orders to a PrintDocument, like so:
I am using the following c# code to generate this:
private void pdPick_PrintPage(object sender, PrintPageEventArgs ev) {
pdPick.DefaultPageSettings.Landscape = true;
pdPick.DefaultPageSettings.Margins = new Margins ( 50, 50, 50, 50 );
pdPick.PrinterSettings.DefaultPageSettings.Margins = new Margins ( 50, 50, 50, 50 );
float yPos;
count = 0;
int leftMargin = (int)ev.MarginBounds.Left;
int rightMargin = (int)ev.MarginBounds.Right;
int topMargin = (int)ev.MarginBounds.Top;
int bottomMargin = (int)ev.MarginBounds.Bottom;
float linesPerPage;
bool moreRecs = true;
int lPos;
// If this is the first page, print a report header
if (pageCounter == 1) {
/* PRINT A REPORT HEADER HERE */
}
else { // if this is a subsequent page, print an abbreviated header
/* PRINT A PAGE HEADER HERE */
}
linesPerPage = ( ev.MarginBounds.Height - yPos ) / ( printFont.GetHeight ( ev.Graphics ) + 3 );
// Cycle through items
while ( curCount < boxCount && count < linesPerPage ) {
// PRINT ITEM DETAIL INFO FIRST...
// Now we cycle through the pick bins for the item...
foreach (PickItem record in pickItems) {
/*
*
* The issue is that I need to check inside this loop to see if I hit the bottom of the page,
* and if so, I need to start a new page and continue printing whatever remains inside this loop.
*
*
*/
}
yPos += 10;
count++;
curCount++;
moreRecs = count < boxItems.Count;
if ( moreRecs ) {
pageCounter++;
ev.HasMorePages = true;
}
else {
pageCounter = 1;
curCount = 0;
yPos += headerFont.Height + 10;
ev.HasMorePages = false;
return;
}
}
}
EDIT I stripped out the printing details to clarify the issue and address comments about refactoring.
The problem is this: As you can see from the code, there are two loops to the print sequence. The first loop obtains a list of products in the pick order, from which I print the title, UPC code, and total units to pick for that item. Inside that loop is another loop where I fetch the list of locations to pick the item from, so there could be multiple locations from which product needs to be retrieved to complete that line item. Now, everything works great as long as I don't go beyond one page. The challenge is this. Obviously I need to do a page break if I have more products that will fit within one page. The problem is, I need to check where I am in the page inside the second loop too, and if so, I need to start a new page and pick up where I left off. For example, with the third product in the list as shown in the included screenshot, if I print the first bin location and then run out of page room, I need to eject the page, print a new page header, then resume printing the rest of the bin locations for that product, then continue with any remaining products in the order.
From everything I can find, I can't simply do a ev.HasMorePages=true; inside that inner loop, because that would cause the entire print sequence to begin again, and that isn't what I want - it would just result in an infinite loop. I have not been able to find any examples or SO posts on printing to a PrintDocument with nested loops.
Can anyone help me understand how to resolve this?

It won't be a tricky issue if you have the
PickItemobjects of each group queued for printing. In this case, all what you need to do:Queue<PickItem>.Yposition remains within theMarginBounds.Yposition plus the fixed/variable line height (your lines/rows calculations for the groups and items) exceeds thee.MarginBounds.Bottomvalue.Example