///<summary>raised for each page to be printed.</summary> private void pd2_PrintPage(object sender, PrintPageEventArgs ev) { //Note that the locations of the reportObjects are not absolute. They depend entirely upon the margins. When the report is initially created, it is pushed up against the upper and the left. Graphics grfx = ev.Graphics; //xPos and yPos represent the upper left of current section after margins are accounted for. //All reportObjects are then placed relative to this origin. Margins currentMargins = null; Size paperSize; if (MyReport.IsLandscape) { paperSize = new Size(1100, 850); } else { paperSize = new Size(850, 1100); } //if(MyReport.ReportMargins==null){ //Crashes MONO. That's ok, because MyReport.ReportMargins is //always null anyway. if (MyReport.IsLandscape) { currentMargins = new Margins(50, 0, 30, 30); } else { currentMargins = new Margins(30, 0, 50, 50); } //} //else{ // currentMargins=MyReport.ReportMargins; //} int xPos = currentMargins.Left; int yPos = currentMargins.Top; int printableHeight = paperSize.Height - currentMargins.Top - currentMargins.Bottom; int yLimit = paperSize.Height - currentMargins.Bottom;//the largest yPos allowed //Now calculate and layout each section in sequence. Section section; //for(int sectionIndex=0;sectionIndex<Report.Sections.Count;sectionIndex++){ while (true) //will break out if no more room on page //if no sections have been printed yet, print a report header. { if (lastSectionPrinted == "") { if (MyReport.Sections.Contains("Report Header")) { section = MyReport.Sections["Report Header"]; PrintSection(grfx, section, xPos, yPos); yPos += section.Height; if (section.Height > printableHeight) //this can happen if the reportHeader takes up the full page //if there are no other sections to print { if (MyReport.ReportTable == null) { //this will keep the second page from printing: lastSectionPrinted = "Report Footer"; } break; } } else //no report header //it will still be marked as printed on the next line { } lastSectionPrinted = "Report Header"; } //If the size of pageheader+one detail+pagefooter is taller than page, then we might later display an error. But for now, they will all still be laid out, and whatever goes off the bottom edge will just not show. This will not be an issue for normal reports: if (MyReport.GetSectionHeight("Page Header") + MyReport.GetSectionHeight("Detail") + MyReport.GetSectionHeight("Page Footer") > printableHeight) { //nothing for now. } //If this is first page and not enough room to print reportheader+pageheader+detail+pagefooter. if (pagesPrinted == 0 && MyReport.GetSectionHeight("Report Header") + MyReport.GetSectionHeight("Page Header") + MyReport.GetSectionHeight("Detail") + MyReport.GetSectionHeight("Page Footer") > printableHeight) { break; } //always print a page header if it exists if (MyReport.Sections.Contains("Page Header")) { section = MyReport.Sections["Page Header"]; PrintSection(grfx, section, xPos, yPos); yPos += section.Height; } //calculate if there is room for all elements including the reportfooter on this page. int rowsRemaining = 0; if (MyReport.ReportTable != null) { rowsRemaining = MyReport.ReportTable.Rows.Count - rowsPrinted; } int totalDetailsHeight = rowsRemaining * MyReport.GetSectionHeight("Detail"); bool isRoomForReportFooter = true; if (yLimit - yPos - MyReport.GetSectionHeight("Report Footer") - MyReport.GetSectionHeight("Page Footer") - totalDetailsHeight < 0) { isRoomForReportFooter = false; } //calculate how many rows of detail to print int rowsToPrint = rowsRemaining; section = MyReport.Sections["Detail"]; if (!isRoomForReportFooter) { int actualDetailsHeight = yLimit - yPos - MyReport.GetSectionHeight("Report Footer") - MyReport.GetSectionHeight("Page Footer"); rowsToPrint = (int)(actualDetailsHeight / MyReport.GetSectionHeight("Detail")); if (rowsToPrint < 1) { rowsToPrint = 1; //Always print at least one row. } } //print the detail section PrintDetailsSection(grfx, section, xPos, yPos, rowsToPrint); if (rowsToPrint == rowsRemaining) //if all remaining rows were printed { lastSectionPrinted = "Detail"; //mark this section as printed. } yPos += section.Height * rowsToPrint; //print the reportfooter section if there is room if (isRoomForReportFooter) { if (MyReport.Sections.Contains("Report Footer")) { section = MyReport.Sections["Report Footer"]; PrintSection(grfx, section, xPos, yPos); yPos += section.Height; } //mark the reportfooter as printed. This will prevent another loop. lastSectionPrinted = "Report Footer"; } //print the pagefooter if (MyReport.Sections.Contains("Page Footer")) { section = MyReport.Sections["Page Footer"]; if (isRoomForReportFooter) { //for the last page, this moves the pagefooter to the bottom of the page. yPos = yLimit - section.Height; } PrintSection(grfx, section, xPos, yPos); yPos += section.Height; } break; } //while pagesPrinted++; //if the reportfooter has been printed, then there are no more pages. if (lastSectionPrinted == "Report Footer") { ev.HasMorePages = false; totalPages = pagesPrinted; ToolBarMain.Buttons["PageNum"].Text = "1 / " + totalPages.ToString(); ToolBarMain.Invalidate(); //labelTotPages.Text="1 / "+totalPages.ToString(); } else { ev.HasMorePages = true; } }