如何在 FlowLayoutPanel 中打印 PictureBoxes 的所有图像

How to print all the Images of PictureBoxes in a FlowLayoutPanel

我正在努力打印由 FlowLayoutPanel 容器托管的 PictureBox-es 的所有图像。

我试过这段代码,但出现异常:

private void PrintAllImages()
{
    imagesToPrintCount = flowLayoutPanel1.Controls.Count;
    PrintDocument doc = new PrintDocument();
    doc.PrintPage += Document_PrintPage;
    PrintDialog dialog = new PrintDialog();
    dialog.Document = doc;

    if (dialog.ShowDialog() == DialogResult.OK)
        doc.Print();
}

private void Document_PrintPage(object sender, PrintPageEventArgs e)
{
    e.Graphics.DrawImage(GetNextImage(), e.MarginBounds);
    e.HasMorePages = imagesToPrintCount > 0;
}

private Image GetNextImage()
{
    //this line I get the error
    PictureBox pictureBox = (PictureBox)flowLayoutPanel2.Controls[flowLayoutPanel2.Controls.Count - imagesToPrintCount];

    imagesToPrintCount--;
    return pictureBox.Image;

}

异常:

System.ArgumentOutOfRangeException: 'Index -2 is out of range. Parameter name: index'

您可以使用 Queue class 来简化任务。

  • 新建 Queue<Image>.
  • FlowLayoutPanelEnqueue 他们的图像中获取 PictureBox-es
  • PrintPage事件中,Dequeue下一张图片并绘制直到队列为空。

我将收缩你的代码到PrintAllImages()方法如下:

using System.Collections.Generic;
using System.Drawing.Printing;
//...

private void PrintAllImages()
{
    var queue = new Queue<Image>();

    flowLayoutPanel2.Controls.OfType<PictureBox>().Where(p => p.Image != null)
        .ToList().ForEach(p => queue.Enqueue(p.Image));

    if (queue.Count == 0) return;

    using (var doc = new PrintDocument())
    using (var pd = new PrintDialog())
    {
        pd.Document = doc;
        if(pd.ShowDialog() == DialogResult.OK)
        {
            doc.PrintPage += (s, e) =>
                {
                    e.Graphics.DrawImage(queue.Dequeue(), e.MarginBounds);
                    e.HasMorePages = queue.Count > 0;
                };
            pd.Document.Print();
        }
    }
}
//...