Home > Net >  click event prints all pages instead print range
click event prints all pages instead print range

Time:06-27

I have the following code for my BeginPrint, PrintPage and Click event. Firing the click event, its printing all pages. I would like to add a print range on button event that prints from-to range:

BeginPrint:

    private void printDocument1_BeginPrint(object sender, System.Drawing.Printing.PrintEventArgs e)
    {
        curRow = 0;
        curCopy = 0;
        if (printrange)
        {
            ((PrintDocument)sender).PrinterSettings.PrintRange = PrintRange.SomePages;
            ((PrintDocument)sender).PrinterSettings.FromPage = 1;
            ((PrintDocument)sender).PrinterSettings.ToPage = 1;
            printrange = false;
        }
    }

PrintPage : I'm generating QRCodes, borders and text in this method. Usually I have more than 2 pages with QRCodes. The problem is that it prints all pages

    private void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
    {
        var curY = e.MarginBounds.Y;
        var curX = e.MarginBounds.X   30;//  10
        Pen pen = new Pen(System.Drawing.ColorTranslator.FromHtml("#FFBD2D"), 1);

        using (var fontNormal = new Font("Arial", 10))
        using (var sf = new StringFormat())
        {
            sf.Alignment = sf.LineAlignment = StringAlignment.Center;
            int itemHeight = (int)fontNormal.GetHeight(e.Graphics);
            

            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(curX, curY, 156, 156);//e.MarginBounds.X
                        var labelRect = new Rectangle(
                            imgRect.X 180 20,//eltol
                            imgRect.Bottom-162,
                            itemHeight,
                            imgRect.Width);

                        using (var qrImage = GenerateQRCODE(dr[1].ToString()))
                        {
                            e.Graphics.DrawImage(RotateImage(qrImage, -90), imgRect);
                        }

                        SizeF labelSize = e.Graphics.MeasureString(dr[1].ToString(), fontNormal);

                        Bitmap stringmap = new Bitmap((int)labelSize.Height   1, (int)labelSize.Width   1);

                        Graphics gbitmap = Graphics.FromImage(stringmap);

                            gbitmap.TranslateTransform(0, labelSize.Width);

                            gbitmap.RotateTransform(-90);

                            gbitmap.DrawString(dr[1].ToString(), fontNormal, Brushes.Black, new PointF(0, 0), new StringFormat());

                            e.Graphics.DrawImage(stringmap, labelRect);

                        gbitmap.Dispose();
                        stringmap.Dispose();

                        e.Graphics.DrawLine(pen, curX, curY, curX, curY   156);//57 |<
                        e.Graphics.DrawLine(pen, curX, curY   156 , curX   156   220, curY   156);// _
                        e.Graphics.DrawLine(pen, curX   156   220, curY   156, curX   156   220, curY);// >|
                        e.Graphics.DrawLine(pen, curX, curY, curX   156   220, curY);// -

                        curX = imgRect.Right   230; //horizontal gap

                        if (curX   imgRect.Width > e.MarginBounds.Right)
                        {
                            curX = e.MarginBounds.X   30;
                            curY = labelRect.Bottom   30;//55vertical gap
                        }

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

                curRow = row   1;
                curCopy = 0;
            }
        }
        refreshprintbtn.Enabled = true;
        printdialogbtn.Enabled = true;
    }

In this click event I'm calling the print() method:

bool printrange = false;
private void printrangebtn_Click(object sender, EventArgs e)
{
    printrange = true;
    printDocument1.BeginPrint  = printDocument1_BeginPrint;
    printDocument1.PrintPage  = printDocument1_PrintPage;
    printDocument1.Print();
}

Thanks

CodePudding user response:

You forgot to implement the PrintRange part in the PrintPage event. Just setting the PrintRange, FromPage, and ToPage properties doesn't mean that the printer knows which page should start with and which one should be the last. These properties exist to get the user inputs through the print dialogs or some setter methods and you need to use them as factors in your implementation.

For example, in PrintRange.SomePages case, use a class field to determine the target pages to print. Increment the field and print only if the value is within the .From and .To range.

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

private int curRow, curCopy, curPage;

public YourForm()
{
    InitializeComponent();
    printDocument1.BeginPrint  = printDocument1_BeginPrint;
    printDocument1.PrintPage  = printDocument1_PrintPage;
}

private void printrangebtn_Click(object sender, EventArgs e)
{
    printDocument1.PrinterSettings.PrintRange = PrintRange.SomePages;
    printDocument1.PrinterSettings.FromPage = 1;
    printDocument1.PrinterSettings.ToPage = 2;
    printDocument1.Print();
}

private void printDocument1_BeginPrint(object sender, PrintEventArgs e)
{
    curRow = 0;
    curCopy = 0;
    curPage = 0;
    // ...
}

private void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
{
    var curY = e.MarginBounds.Y;
    var curX = e.MarginBounds.X   30;//  10
    var doc = sender as PrintDocument;

    using (var pen = new Pen(ColorTranslator.FromHtml("#FFBD2D")))
    using (var fontNormal = new Font("Arial", 10))
    using (var sf = new StringFormat())
    {
        sf.Alignment = sf.LineAlignment = StringAlignment.Center;
        int itemHeight = (int)fontNormal.GetHeight(e.Graphics);

        for (int row = curRow; row < dt.Rows.Count; row  )
        {
            curPage  ;

            var doPrint = doc.PrinterSettings.PrintRange != PrintRange.SomePages ||
            (curPage >= doc.PrinterSettings.FromPage && curPage <= doc.PrinterSettings.ToPage);

            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(curX, curY, 156, 156);//e.MarginBounds.X
                    var labelRect = new Rectangle(
                        imgRect.X   180   20,//eltol
                        imgRect.Bottom - 162,
                        itemHeight,
                        imgRect.Width);

                    // If not, don't print and continue the calculations...
                    if (doPrint)
                    {
                        using (var qrImage = GenerateQRCODE(dr[1].ToString()))
                            e.Graphics.DrawImage(RotateImage(qrImage, -90), imgRect);

                        SizeF labelSize = e.Graphics.MeasureString(dr[1].ToString(), fontNormal);
                        Bitmap stringmap = new Bitmap((int)labelSize.Height   1, (int)labelSize.Width   1);
                        Graphics gbitmap = Graphics.FromImage(stringmap);

                        gbitmap.TranslateTransform(0, labelSize.Width);
                        gbitmap.RotateTransform(-90);
                        gbitmap.DrawString(dr[1].ToString(), fontNormal, Brushes.Black, new PointF(0, 0), new StringFormat());

                        e.Graphics.DrawImage(stringmap, labelRect);

                        gbitmap.Dispose();
                        stringmap.Dispose();

                        e.Graphics.DrawLine(pen, curX, curY, curX, curY   156);//57 |<
                        e.Graphics.DrawLine(pen, curX, curY   156, curX   156   220, curY   156);// _
                        e.Graphics.DrawLine(pen, curX   156   220, curY   156, curX   156   220, curY);// >|
                        e.Graphics.DrawLine(pen, curX, curY, curX   156   220, curY);// -
                    }

                    curX = imgRect.Right   230; //horizontal gap

                    if (curX   imgRect.Width > e.MarginBounds.Right)
                    {
                        curX = e.MarginBounds.X   30;
                        curY = labelRect.Bottom   30;//55vertical gap
                    }

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

            if (!doPrint)
            {
                curX = e.MarginBounds.X;
                curY = e.MarginBounds.Y;
            }

            curRow = row   1;
            curCopy = 0;
        }
    }
    refreshprintbtn.Enabled = true;
    printdialogbtn.Enabled = true;
}

Side Notes

  • You shouldn't add handlers for the PrintDocument events each time you click a Button unless you remove the current handlers first in the EndPrint for example. Just add them once as shown in the Form's ctor or Load event.
  • System.Drawing.Pen is a disposable object so you need to dispose of it as well. Create it with the using statement or pass an instance using (pen) ... or call the .Dispose(); method explicitly. Do the same for any object implements the IDisposable interface.
  • Related