Saeed Jafari
Saeed Jafari

Reputation: 1

PrintDocument HasMorePages don't work

I want to print the data from data grid. The code works well for the first page, but the commented lines do not works well and don't move to next page. Can anyone help fix this?

private void DrawFactorA4(object sender, PrintPageEventArgs ev)
    {
     for (int j = 0; j < GrdRDocument.Rows.Count; j++)
        {
            i += 2;
            //draw data grid
            s++;
            if(s == 10)
            {    
               //ev.HasMorePages = true;  //this line doesn't work
               s = 0;
               i = 0;                 
            }
            else
            {
               ev.HasMorePages = false;                    
            }
        }
    }

_

private void BtnPrint_Click(object sender, EventArgs e)
    {
        printFont = new Font("Arial", 12);

        IEnumerable<PaperSize> paperSizes = 

        pd.PrinterSettings.PaperSizes.Cast<PaperSize>();

        sizeA4 = paperSizes.First<PaperSize>(size => size.Kind == PaperKind.A4);

        pd.DefaultPageSettings.Landscape = true;

        pd.DefaultPageSettings.PaperSize = sizeA4;

        pd.PrintPage += new PrintPageEventHandler(this.DrawFactorA4);

        printPreviewDialog.Document = pd;

        printPreviewDialog.ShowDialog();
    }

Upvotes: 0

Views: 1033

Answers (1)

Dour High Arch
Dour High Arch

Reputation: 21712

Stop and read what you have:

printFont = new Font("Arial", 12);

Fonts are unmanaged resources; here you're instantating one and never disposing it. Maybe that's harmless in this particular situation, but this is a bad habit to get in to.

pd.PrintPage += new PrintPageEventHandler(this.DrawFactorA4);

DrawFactorA4 is going to be called for every page in your document. Inside DrawFactorA4:

for (int j = 0; j < GrdRDocument.Rows.Count; j++)

You iterate through every Row in GrdRDocument, regardless the number of rows or the size of your page. That is wrong; you have to stop after the page is filled. By the way, I hope GrdRDocument is a local copy of immutable data and you're not passing UI controls to the printing thread.

s++;
if(s == 10)
{    
    //ev.HasMorePages = true;  //this line doesn't work
    s = 0;

Your commented line would work fine. The problem is you set ev.HasMorePages = true and then ignore it; you set s = 0 and keep iterating; next iteration s!=10 so you:

    ev.HasMorePages = false;

Read the PrintDocument docs; it has an example of printing more than one page. You should create a class to store all the unmanaged resources and page state. Make it IDisposable so they get disposed. Iterate through only the rows or whatever you want to print on each page. Something like:

class PrintStuff : IDisposable
{
    readonly IEnumerable<Whatever> data;
    readonly PrintDocument pd;
    Font font;
    private int currentIndex;

    public PrintStuff(IEnumerable<Whatever> data)
    {
        this.data = data;

        pd = new PrintDocument();
        pd.BeginPrint += OnBeginPrint;
        pd.PrintPage += OnPrintPage;
        pd.EndPrint += OnEndPrint;
    }

    public void Print()
    {
        pd.Print();
    }

    public void Dispose()
    {
        pd.Dispose();
    }

    private void OnBeginPrint(object sender, PrintEventArgs args)
    {
        font = new Font(FontFamily.GenericSansSerif, 12F);
        currentIndex = 0;
    }

    private void OnEndPrint(object sender, PrintEventArgs args)
    {
        font.Dispose();
    }

    private void OnPrintPage(object sender, PrintPageEventArgs args)
    {
        var x = Convert.ToSingle(args.MarginBounds.Left);
        var y = Convert.ToSingle(args.MarginBounds.Top);
        var lineHeight = font.GetHeight(args.Graphics);
        while ((currentIndex < data.Count())
               && (y <= args.MarginBounds.Bottom))
        {
            args.Graphics.DrawWhatever(data.ElementAt(currentIndex), font, Brushes.Black, x, y);
            y += lineHeight;
            currentIndex++;
        }

        args.HasMorePages = currentIndex < data.Count();
    }
}

Upvotes: 2

Related Questions