使用e.HasMorePages打印新页面
本文关键字:新页面 打印 HasMorePages 使用 | 更新日期: 2023-09-27 18:12:08
我有点困惑如何使用HasMorePages
属性。我正试图通过YPosition
方法打印一些页面,但它会导致打印页面的无限循环。
这是我的代码:
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
表示页面中每行或图像的高度。
如果所有的对象都被处理了,我怎么能防止无休止的循环打印和停止?
需要使用while循环和Enumerator来代替for循环。枚举数保留正在处理的对象的状态,并将其作为窗体实例的成员存储。使用PrintDocument类的BeginPrint和EndPrint事件来初始化和清理枚举器。
// this is the variable that holds the enumerator instance
// once printing has started
IEnumerator<Tuple<Object, LineTypes>> ObjectsEnumerator;
// this is the event raised by printdocument at the start of printing
private void printDocument1_BeginPrint(object sender, System.Drawing.Printing.PrintEventArgs e)
{
this.ObjectsEnumerator = Objects.GetEnumerator();
}
因为我们现在有一个枚举器,PrintPage实现将使用它。它调用MoveNext并将结果存储在HasMorePages
中。代码的其余部分与您所拥有的类似,但请确保将页面位置的计算保留在方法的本地。不要(ab)为此使用实例变量。注意,对Current
的调用是while循环中的第一条语句。
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
int linesCount = 0;
float yPosition = 10;
// take the next item from the list by calling MoveNext
// and assign the outcome to e.HasMorePages
while(e.HasMorePages = this.ObjectsEnumerator.MoveNext())
{
var tuple = this.ObjectsEnumerator.Current;
switch (tuple.Item2)
{
case LineTypes.LINE:
// draw magic
e.Graphics.DrawString(tuple.Item1.ToString(), font, solidBrush, new PointF(10,yPosition));
yPosition += 300;
linesCount++;
break;
case LineTypes.IMAGE:
Image Image = (Image)tuple.Item1;
// e.Graphics.DrawImage(....);
// calculate new yPosition
yPosition += Image.Height;
break;
}
// if we reach the end of the page
if (yPosition >= e.PageSettings.PrintableArea.Height)
{
//we break out of the while loop
// e.HasMorePages is already set
break;
}
}
}
用这段代码,你可以遍历你的集合,如果页面满了就跳出循环,当没有更多的项目要打印时就停止迭代和打印。
如果打印完成,调用Endprint,它的任务是清理枚举数。
private void printDocument1_EndPrint(object sender, System.Drawing.Printing.PrintEventArgs e)
{
if (this.ObjectsEnumerator != null)
{
this.ObjectsEnumerator.Dispose();
this.ObjectsEnumerator = null;
}
}