0

I got a windows form which has more than one page of mainly labels and textboxes, I'm trying to keep the font that i have in the winform already, so far I'm able to print the first page, but when i try to add the rest of the controls it does all sort of weird stuff this is the part of my code where i'm putting everything to print but not all the controls in the panel show in the print preview. So i found out that the controls in the panel are not in order and what i need to do is create the number of printing pages first then put the controls in those printing pages. any help on trying to create the print pages first to add the controls to it. it will always be 4 print pages.

    int mainCount = 0;
    public void printStuff(System.Drawing.Printing.PrintPageEventArgs e)
    {            
        Font printFont = new Font("Arial", 9);
        int dgX = dataGridView1.Left;
        int dgY = dataGridView1.Top += 22;
        double linesPerPage = 0;
        float yPos = 0;
        int count = 0;

        float leftMargin = e.MarginBounds.Left;
        float topMargin = e.MarginBounds.Top;
        float bottomMargin = e.MarginBounds.Bottom;
        StringFormat str = new StringFormat();

        linesPerPage = e.MarginBounds.Height / printFont.GetHeight(e.Graphics);
        Control ctrl;

        while ((count < linesPerPage) && (panel1.Controls.Count != mainCount))           
        {
            ctrl = panel1.Controls[mainCount];
            yPos = topMargin + (count * printFont.GetHeight(e.Graphics));
            mainCount++;
            count++;
            if (ctrl is Label)
            {
                e.Graphics.DrawString(ctrl.Text, printFont, Brushes.Black, ctrl.Left + 5, ctrl.Top + 40);
            }
            else if (ctrl is TextBox)
            {
                e.Graphics.DrawString(ctrl.Text, printFont, Brushes.Black, ctrl.Left + 5, ctrl.Top + 40);
                e.Graphics.DrawRectangle(Pens.Black, ctrl.Left, ctrl.Top + 40, ctrl.Width, ctrl.Height);
            }
        }
        if (count > linesPerPage)
        {
            e.HasMorePages = true;
        }
        else
        {
            e.HasMorePages = false;
        }            
    }

    //Print
    private void exportFileToolStripMenuItem_Click(object sender, EventArgs e)
    {            
        printPreviewDialog1.Document = printDocument1;
        printPreviewDialog1.ShowDialog();
    }

    private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
    {
        printStuff(e);
    }
Ubaldo Quintero
  • 169
  • 3
  • 15
  • and what exactly are these weird things it does? – Mike Dinescu Mar 07 '13 at 16:53
  • after the first page it prints the other controls all over the page and a lot of the pages are blank – Ubaldo Quintero Mar 07 '13 at 16:57
  • The code assumes that *mainCount* has something to do with what page a control should be printed on. This is not the case, the Location property of a control is what matters. Which also has to be adjusted for the page number. And BeginPrint is missing to reset the counter back to 0. Having a form not fit on a piece of paper is also very unusual. – Hans Passant Mar 07 '13 at 17:51
  • Thanks Hans, I just realized that, I guess i can put ranges on the location of the control that i'm trying to add, but i think is a lot more efficient and easier to create the 4 pages that i need first then lay all the controls on them, I just can't figure out how to create the pages first – Ubaldo Quintero Mar 07 '13 at 18:35

1 Answers1

0

It seems to me that the problem is that on subsequent pages you are not subtracting the "page offset" form the control Top positions when printing. You are essentially trying to use the screen coordinates of the controls when placing them on the printed page which obviously only works correctly for the first page. On subsequent pages you need to map the screen coordinates by subtracting a quantity which is the equivalent of the "total-printed-surface-so-far"..

You will want to modify this line for instance:

e.Graphics.DrawString(ctrl.Text, printFont, Brushes.Black, ctrl.Left + 5, ctrl.Top + 40);

to something like this:

e.Graphics.DrawString(ctrl.Text, printFont, Brushes.Black, ctrl.Left + 5, ctrl.Top + 40 - pageOffset);

where the pageOffset is a variable that should be computed for each page, based on the Height of the printable area: pageOffset = currentPageNumber * heightOfPrintableArea so you will also need to maintain a variable for the number of pages printed, similar to the mainCount

Of course, the same would apply to the other branch of your if statement:

e.Graphics.DrawString(ctrl.Text, printFont, Brushes.Black, ctrl.Left + 5, ctrl.Top + 40 - pageOffset);
e.Graphics.DrawRectangle(Pens.Black, ctrl.Left, ctrl.Top + 40 - pageOffset, ctrl.Width, ctrl.Height);
Mike Dinescu
  • 54,171
  • 16
  • 118
  • 151
  • I'll try that, but how would i get the height of Printable area? – Ubaldo Quintero Mar 07 '13 at 17:07
  • you could try using e.MarginBounds.Height as the height of the printable area. See if that produces the results you are looking for. And as I said, use another variable to keep track of which page you are printing, incrementing it with each call to printStuff(..) – Mike Dinescu Mar 07 '13 at 17:10