I'm a little confused how I can use the HasMorePages
property. I'm trying to print some page more depending by the YPosition
method, but it causes an infinite loop of printing pages.
This is my code:
private float YPosition()
{
return this.TopMargin + ((float)this.LinesCount * this.Font.GetHeight(this.Graphics) + (float)this.ImagesHeight);
}
private void TicketPrintPage(object sender, PrintPageEventArgs e)
{
e.Graphics.PageUnit = GraphicsUnit.Millimeter;
this.Graphics = e.Graphics;
foreach (Tuple<Object, LineTypes> tuple in this.Objects)
{
switch (tuple.Item2)
{
case LineTypes.LINE:
this.Graphics.DrawString((String)tuple.Item1, this.Font, this.SolidBrush, this.LeftMargin, this.YPosition(), new StringFormat());
this.LinesCount++;
break;
case LineTypes.IMAGE:
Image Image = (Image)tuple.Item1;
// Center Image, using PaperSize
Graphics GraphicsImage = Graphics.FromImage(Image);
RectangleF RectangleF = e.MarginBounds;
RectangleF.Offset(-e.PageSettings.HardMarginX, -e.PageSettings.HardMarginY);
float InchX = RectangleF.X / 100f + (RectangleF.Width / 100f - (float)Image.Width / GraphicsImage.DpiX) / 2f;
Int32 MillimeterX = (Int32)Math.Ceiling(InchX / 0.039370);
this.Graphics.DrawImage(Image, new Point((int)this.LeftMargin + (MillimeterX / 2), (int)this.YPosition()));
double a = (double)Image.Height / 58.0 * 15.0;
this.ImagesHeight += (int)Math.Round(a) + 3;
break;
}
if ((YPosition() * 4) >= e.PageSettings.PrintableArea.Height)
{
e.HasMorePages = true;
return;
}
else
{
e.HasMorePages = false;
}
}
}
YPosition
represent the height of each line or images in the pages.
How can I prevent the endless loop of printing and stop if all Objects are handled?
Instead of a for loop you need to use a while loop and an Enumerator. The enumerator keeps the state of which object you're handling and that is stored as a member on the form instance. Use the BeginPrint and EndPrint event of the PrintDocument class to initialize and clean-up the enumerator.
As we now have an enumerator the PrintPage implementation is going to use that. It calls MoveNext and stores the result in
HasMorePages
. The rest of the code is similar to what you had but make sure to keep the calculation of the position on the page local to the method. Don't (ab)use instance variables for that. Notice the call toCurrent
as the first statement in the while loop.With this code you can iterate over your collection, break out of the loop if the page is full and stop iterating and printing when there are no more items to print.
If printing is done Endprint is called and its task is to clean-up the enumerator.