I'm struggling to print all the images of PictureBox-es
which are hosted by a FlowLayoutPanel
container.
I've have tried this code but I'm getting an exception:
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;
}
The Exception:
System.ArgumentOutOfRangeException: 'Index -2 is out of range. Parameter name: index'
You can simplify the task by using the Queue class.
Queue<Image>
.PictureBox-es
from the FlowLayoutPanel
and Enqueue their images.PrintPage
event, Dequeue the next image and draw it until the queue is empty.I'll shrink your code to the PrintAllImages()
method as follows:
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();
}
}
}
//...