SubjectX
SubjectX

Reputation: 896

Print multiple pages in WinForms doesn't work

Coming from Question

which was answered really quick, I have stumbled upon upgraded problem.

I have changed my program to fill some DataSet from DB.

I call Print() on printDocument, everything works, it just doesn't want to register my e.HasMorePages = true;

Here is code:

   public static void printDokument()
   {
       if (result == DialogResult.OK)
       {

           DbDataPostavke = checkDB("SELECT * FROM " + tipDokumenta + "_postavke WHERE ID_" + tipDokumenta + " = " + stDokumenta);

           list = DbDataPostavke.Tables[0].AsEnumerable().ToList();                             
           printDocument.Print();
       }       
   }

   static void printDocument_PrintPage(object sender, PrintPageEventArgs e)
   {
       graphic = e.Graphics;

       e.PageSettings.PaperSize = ps;

       stranSirina = e.PageSettings.PrintableArea.Width;
       stranVisina = e.PageSettings.PrintableArea.Height;

       fontHeight = font.GetHeight();

       //this works/prints
       printDocument_PrintHeader();

       //this works/prints
       printDocument_PrintDocumentInfo();

       if (firstPage) printDocument_PrintSupplierInfo();    

       //Lines that I take from DB, amount of this lines is variable //it only prints one page, then it stops printing
       printDocument_PrintProductLines(e);

       //Sum of lines
       if(zadnjaStran) printDocument_printSum();

       //prints comment on document
       if (zadnjaStran) printDocument_PrintComment();

       //footer
       printDocument_PrintFooter();
   }

   static void printDocument_PrintProductLines(PrintPageEventArgs e)
   {
       //I print some stuff here (header, etc..) 

       String stranArtikliVrstica = String.Empty; // string for one line of data
       DataRow dataRow1 = null;
       DataRow dr = null;

       for(int i = 0; i < list.Count(); i++)
       {
           dr = list[i];
           dataRow1 = poglejBazo("SELECT ime, EM, opis FROM Sifrant WHERE ID = " + dr[2].ToString()).Tables[0].Rows[0];

           stranArtikliVrstica = String.Format("{0,-38}  {1,10}  {2,5}  {3,9:C}  {4,9:C}", dataRow1[0].ToString() + " - " + dataRow1[2].ToString(), dr[3].ToString(), dataRow1[1].ToString(), dr[4], Convert.ToInt16(dr[3]) * Convert.ToInt16(dr[4]));

           list.Remove(dr);

           graphic.DrawString(stranArtikliVrstica, font, brush, startX + offsetX, startY + offsetY);
           offsetY += (int)font.GetHeight();

           //if there is less then 35 "lines" remaining, we have enough space for printing some other stuff, otherwise, that stuff doesn't print..
           if (list.Count() < 35) zadnjaStran = true;
           else zadnjaStran = false;

           if (offsetY > stranVisina - 50)
           {
               prvaStran = false;
               stevecStrani++;
               offsetY = 0;
               e.HasMorePages = true;
               return;
           }
       }

   }

So, when I try to print a document with a single page, everything works, but if I try to print a document with multiple pages, only the first page prints (Header, DocumentInfo, SupplierInfo, ProductLines (around 38 lines out of 80), Footer) and then there is no more pages (I'm testing with printing into PDF file..)

What am I doing wrong?

Is there a problem with e parameter in PrintProductLines? How can I tell function PrintProductLines that I want to trigger HasMorePages on e from original function? I know I can pass it by reference, but ref keyword doesn't work in my case :S

EDIT:

Changing static void printDocument_PrintProductLines(ref PrintPageEventArgs e) and printDocument_PrintProductLines(ref e); throws an error:

Error 2 Argument 1 must be passed with the 'ref' keyword
Error 1 The best overloaded method match for 'GZIG.globalClass.printDocument_PrintPostavke(ref System.Drawing.Printing.PrintPageEventArgs)' has some invalid arguments

Upvotes: 0

Views: 1730

Answers (1)

user153923
user153923

Reputation:

You should not be placing printing code like this into a static global class.

This routine belongs in the actual instance of the class that will be using the Graphics object.

private const int PAD = 4;
private int m_Line, m_LinesToPrint;
private Font m_Font;
private PrintDocument m_Doc;

private void print_Click(object sender, EventArgs e) {
  using (var dlg = new PrintPreviewDialog()) {
    if (m_Doc == null) {
      throw new NullReferenceException("Create the document before trying to print it.");
    }
    dlg.Document = m_Doc;
    m_Line = 0;
    m_LinesToPrint = list.Count;
    m_Font = new Font("Courier New", 14, FontStyle.Underline, GraphicsUnit.Point);
    dlg.ShowDialog();
  }
}

private void printDocument1_PrintPage(object sender, PrintPageEventArgs e) {
  float lineHeight = m_Font.GetHeight(e.Graphics) + PAD;
  float yLineTop = e.MarginBounds.Top;
  for ( ; m_Line < m_LinesToPrint; m_Line++) {
    if (e.MarginBounds.Bottom < (yLineTop + lineHeight)) {
      e.HasMorePages = true;
      return;
    }
    DataRow dr = list[m_Line];
    DataRow row1 = poglejBazo("SELECT ime, EM, opis FROM Sifrant WHERE ID = " + dr[2].ToString()).Tables[0].Rows[0];
    string strText = String.Format("{0,-38}  {1,10}  {2,5}  {3,9:C}  {4,9:C}", dataRow1[0].ToString() + " - " + dataRow1[2].ToString(), dr[3].ToString(), dataRow1[1].ToString(), dr[4], Convert.ToInt16(dr[3]) * Convert.ToInt16(dr[4]));
    // list.Remove(list[m_Line]) <= DO NOT DO THAT!
    e.Graphics.DrawString(strText, m_Font, Brushes.Black, new PointF(e.MarginBounds.Left, yLineTop));
    yLineTop += lineHeight;
  }
  e.HasMorePages = false;
}

Upvotes: 2

Related Questions