Home > Back-end >  Infinite pages generated with e.HasMorePages
Infinite pages generated with e.HasMorePages

Time:06-22

I generate several QRCodes and would like to print the barcodes one after another on an A4 size page in Print Preview Control. I also use this control: PrintBar I calculated, that about 5 QRCodes can be on an A4 format page, so I tried to split with HasMorePages.

Print Preview without HasMorePages: the A4 page with the QRCodes screenshot - the last QRCode should be on the last page.

I added e.HasMorePages and return, but is not working correctly...It counts the pages to infinite and after that crashes.

My code:

BeginPrint

    private void printDocument1_BeginPrint(object sender, System.Drawing.Printing.PrintEventArgs e)
    {
        this.currentItem = 0;
    }

PrintPage

    private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
    {
        String fontName = "Arial";
        Font fontNormal = new Font(fontName, 12, System.Drawing.FontStyle.Regular);
        float itemHeight = fontNormal.GetHeight(e.Graphics);
        Brush normalColour = Brushes.Black;
        float leftMargin = e.MarginBounds.Left;
        float topMargin = e.MarginBounds.Top;
        float printWidth = e.MarginBounds.Width;
        float printHeight = e.MarginBounds.Height;
        float rightMargin = leftMargin   printWidth;
        float currentPosition = topMargin;
        float numberWidth = 70;
        float lineWidth = printWidth - numberWidth;
        float lineLeft = leftMargin;
        float numberLeft = leftMargin   lineWidth;

        int items = 0;

        foreach (DataRow dr in dt.Rows)
        {
            if (!dr[4].Equals(""))
                items  = Convert.ToInt32(dr[4].ToString());
            else
                items  = 0;
        }

        noOfItems = items;

        foreach (DataRow dr in dt.Rows)
        {
            Bitmap bt = null;
            if (!dr[1].Equals(""))
            {
                if (!dr[4].Equals(""))
                {
                    int nrcodes = Convert.ToInt32(dr[4].ToString());//in the 4th row the value means how many QRCodes should be generated

                    for (int i = 0; i < nrcodes; i  )
                    {
                        if (i % 5 != 0)
                        {
                            bt = GenerateQRCODE(dr[1].ToString());//dr[1] QRCode value
                            e.Graphics.DrawImage(bt, leftMargin, currentPosition, 200, 200);
                            e.Graphics.DrawString(dr[1].ToString(), fontNormal, normalColour, leftMargin   40, currentPosition   180); //dr[1] - text under QR Code
                        }
                        else
                        {
                            e.HasMorePages = true;
                            return;
                        }
                        currentPosition  = 200;
                    }
                }
            }   
        }
       // e.HasMorePages = true;
    }

CodePudding user response:

Yes, I need to print the same QR Code as many times as in the dr[4] column value. After that the next QR Code the same way.

In this case you need to keep track of the current DataRow and n copy to not repeat the same code for the same row and copy when you set e.HasMorePages = true;. For the copies, request a new page if the bottom of the current output block exceeds the e.MarginBounds.Bottom. To request a new page for each row, uncomment the last lines of the following example.

//  
using System.Drawing.Printing;
// ...

private int curRow = 0;
private int curCopy = 0;

// Or from where you call `.Print();`
// Button.Click event for example.
private void printDocument1_BeginPrint(object sender, PrintEventArgs e)
{
    curRow = 0;
    curCopy = 0;
}

private void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
{
    var curY = e.MarginBounds.Y;

    using (var fontNormal = new Font("Arial", 12))
    using (var sf = new StringFormat())
    {
        sf.Alignment = sf.LineAlignment = StringAlignment.Center;
        int itemHeight = (int)fontNormal.GetHeight(e.Graphics)   10;
        
        for (int row = curRow; row < dt.Rows.Count; row  )
        {
            DataRow dr = dt.Rows[row];

            if (!string.IsNullOrEmpty(dr.Field<string>(1)) &&
                int.TryParse(dr.Field<string>(4)?.ToString(), out int copies))
            {
                for (int i = curCopy; i < copies; i  )
                {
                    var imgRect = new Rectangle(e.MarginBounds.X, curY, 200, 200);
                    var labelRect = new Rectangle(
                        imgRect.X, 
                        imgRect.Bottom, 
                        imgRect.Width, 
                        itemHeight);

                    if (curY   imgRect.Height   labelRect.Height >= e.MarginBounds.Bottom)
                    {
                        curCopy = i;
                        e.HasMorePages = true;
                        return;
                    }

                    e.Graphics.DrawImage(bmp, imgRect);
                    e.Graphics.DrawString(dr[1].ToString(), 
                        fontNormal, Brushes.Black, 
                        labelRect, sf);

                    curY = labelRect.Bottom   30;
                }
            }

            curRow = row   1;
            curCopy = 0;

            // Uncomment if you want to start a new
            // page for each row.
            //if (row < dt.Rows.Count - 1)
            //{
            //    e.HasMorePages = true;
            //    break;
            //}
    }
}
  • Related