使用e.HasMorePages打印新页面

时间:2015-09-10 20:49:42

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

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

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

1 个答案:

答案 0 :(得分:1)

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

function getInput() {
  console.log("Please choose either 'rock', 'paper', or 'scissors'.");
  return prompt();
}

function randomPlay() {
  var randomNumber = Math.random();
  if (randomNumber < 0.33) {
    return "rock";
  } else if (randomNumber < 0.66) {
    return "paper";
  } else {
    return "scissors";
  }
}
console.log(randomPlay());

function getPlayerMove(move) {
  if (!move) {
    move = getInput();
  }
  return move;
}

function getComputerMove(move) {
  if (!move) {
    move = getInput();
  }
  return move;
}

function getWinner(playerMove, computerMove) {
  if (playerMove === computerMove) {
    return ("It's a tie!");
  } else if (playerMove === "rock") {
    if (computerMove === "paper") {
      return "paper wins";
    } else {
      return "rock wins";
    }
  } else if (playerMove === "paper") {
    if (computerMove === "rock") {
      return "paper wins";
    } else {
      return "scissors wins";
    }
  } else if (playerMove === "scissors") {
    if (computerMove === "paper") {
      return "scissors wins";
    } else {
      return "rock wins";
    }
  }
}

console.log(getWinner(getPlayerMove(), getComputerMove()));

由于我们现在有一个枚举器,PrintPage实现将使用它。它调用MoveNext并将结果存储在// 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(); } 中。其余代码与您所拥有的类似,但请确保在方法的本地页面上保持位置的计算。不要(ab)使用实例变量。注意调用Current作为while循环中的第一个语句。

HasMorePages

使用此代码,您可以遍历您的集合,如果页面已满,则跳出循环,并在没有其他项目打印时停止迭代和打印。

如果打印完成,则调用Endprint,其任务是清理枚举器。

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