【问题标题】:Printing new pages with e.HasMorePages使用 e.HasMorePages 打印新页面
【发布时间】:2015-09-10 20:49:42
【问题描述】:

我有点困惑如何使用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代表页面中每一行或图片的高度。

如果所有对象都被处理,如何防止打印的无限循环并停止?

【问题讨论】:

    标签: c# .net winforms visual-studio drawing


    【解决方案1】:

    您需要使用while 循环和Enumerator,而不是for 循环。枚举器保持您正在处理的对象的状态,并将其作为成员存储在表单实例上。使用PrintDocument 类的BeginPrintEndPrint 事件来初始化和清理枚举器。

    // 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;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-09-22
      • 1970-01-01
      • 1970-01-01
      • 2018-09-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多