PrintPage PrintPageEventHandler prints too many copies

I must print shipping labels for products that our company produces.

To help me feel how these shortcuts work, I design them using Windows Form. This allows me to position my text, install fonts correctly, etc. Using the controls Label, add a custom control BarCodeand get a "quirkiness" with controls Panelto group items into fields.

Each page contains two (2) tags.

When my code prints a tag document, I request either 2, 4, or 6 copies. Sometimes a preview is also used. In this case, I must reset to create the number of labels created.

However, when documents are printed:

  • if the request is designed for 2 copies, the code prints 2 sheets of paper (4 marks)
  • If the request is designed for 4 copies, the code prints 8 sheets of paper (16 labels)
  • If the request is designed for 6 copies, the code prints a whopping 18 pages (36 labels)

Does anyone see the template? I do not do this.

This is my Print command:

public int Print(string docName, int rows, int columns, int copies) {
  short shortCopies = (short)copies;
  LabelsHorizontal = rows;
  LabelsVertical = columns;
  Size docSize = PrintPreview.Document.DefaultPageSettings.Bounds.Size;
  float height = 0.8F * Screen.PrimaryScreen.WorkingArea.Size.Height;
  float width = (height * docSize.Width) / docSize.Height;
  Size winSize = new Size((int)width, (int)height);
  PrintPreview.Height = winSize.Height;
  PrintPreview.Width = winSize.Width;
  if (!String.IsNullOrEmpty(docName)) {
    PrintPreview.Document.DocumentName = docName;
  }
  PrintPreview.Document.PrinterSettings.Copies = shortCopies;
  PrintPreview.SettingsFilename = Settings.PageSettingsLocation;
  if (!PrintPreview.PrinterSelected) {
    if (PrintPreview.ShowPrinterSelectDialog() != DialogResult.OK) {
      return 0;
    }
  }
  labelQtyPrinted = 0;
  if (ShowPrintPreview) {
    PrintPreview.ShowDialog();
  } else {
    PrintPreview.PrintDocument();
  }
  return labelQtyPrinted;
}
// Resets the Label Count between PrintPreview and Print
private void PrintPreview_OnPrintClicked(object sender, EventArgs e) {
  labelQtyPrinted = 0;
}

I had to write my own PrintPreview class that accepts PrintPreviewDialogas a base class so that I can override its Print button using this printButton_Click method :

// Handles the Printing of the Document
internal void printButton_Click(object sender, EventArgs e) {
  if (OnPrintClicked != null) {
    OnPrintClicked(sender, e); // this resets my labelQtyPrinted value shown above
  }
  Document.Print();
  printed = true;
  Close();
}

In a method Print(the first piece of code) PrintPreview.PrintDocument()is just the code that triggers the event printButton_Click.

My PrintPageEventHandler is shown below:

private void Document_Printed(object sender, PrintPageEventArgs e) {
  if (PrintPreview.Document.PrinterSettings.Copies <= labelQtyPrinted) {
    throw new Exception("Run Away Printer");
  }
  float scale;
  SizeF pageSize = new SizeF(
    PrintPreview.Document.DefaultPageSettings.PaperSize.Width,
    PrintPreview.Document.DefaultPageSettings.PaperSize.Height
  );
  Margins m = PrintPreview.Document.DefaultPageSettings.Margins;
  float printableHeight = pageSize.Height - (m.Top + m.Bottom);
  float printableWidth = pageSize.Width - (m.Left + m.Right);
  if (printableWidth < printableHeight) {
    if (labelSize.Width < labelSize.Height) {
      float r1 = (printableWidth) / labelSize.Width;
      float r2 = (printableHeight) / labelSize.Height;
      scale = (r1 < r2) ? r1 : r2;
    } else {
      scale = (printableWidth) / labelSize.Width;
    }
  } else {
    if (labelSize.Width < labelSize.Height) {
      scale = (printableHeight) / labelSize.Height;
    } else {
      float r1 = (printableWidth) / labelSize.Width;
      float r2 = (printableHeight) / labelSize.Height;
      scale = (r1 < r2) ? r1 : r2;
    }
  }
  float lh = scale * labelSize.Height;
  float lw = scale * labelSize.Width;
  float ml = scale * m.Left;
  float mt = scale * m.Top;
  Graphics G = e.Graphics;
  G.SmoothingMode = smoothMode;
  G.TextRenderingHint = TextRenderingHint.AntiAlias;
  for (int i = 0; i < LabelsHorizontal; i++) {
    float dx = i * (lw + ml); // Horizontal shift * scale
    for (int j = 0; j < LabelsVertical; j++) {
      float dy = j * (lh + mt); // Vertical shift * scale
      #region ' Panels '
      foreach (Panel item in panels) {
        float h = scale * item.Size.Height;
        float w = scale * item.Size.Width;
        float x = (ml + dx) + scale * item.Location.X;
        float y = (mt + dy) + scale * item.Location.Y;
        using (SolidBrush b = new SolidBrush(item.BackColor)) {
          G.FillRectangle(b, x, y, w, h);
        }
        using (Pen p = new Pen(Brushes.Black)) {
          G.DrawRectangle(p, x, y, w, h);
        }
      }
      #endregion
      #region ' Logo '
      if (logo != null) {
        float h = scale * logo.Height;
        float w = scale * logo.Width;
        float x = (ml + dx) + scale * logoPt.X;
        float y = (mt + dy) + scale * logoPt.Y;
        G.DrawImage(logo, x, y, w, h);
      }
      #endregion
      #region ' Labels '
      foreach (Label item in labels) {
        float h = scale * item.Size.Height;
        float w = scale * item.Size.Width;
        float x = (ml + dx) + scale * item.Location.X;
        float y = (mt + dy) + scale * item.Location.Y;
        Color c = PrintPreview.Document.DefaultPageSettings.Color ? item.ForeColor : Color.Black;
        Font font = new Font(item.Font.FontFamily, scale * item.Font.Size, item.Font.Style);
        using (SolidBrush b = new SolidBrush(c)) {
          StringFormat format = GetStringFormatFromContentAllignment(item.TextAlign);
          format.FormatFlags = StringFormatFlags.NoClip | StringFormatFlags.NoWrap;
          format.Trimming = StringTrimming.None;
          PointF locationF = new PointF(x, y);
          SizeF size = new SizeF(w, h);
          RectangleF r = new RectangleF(locationF, size);
          G.DrawString(item.Text, font, b, r, format);
        }
      }
      #endregion
      #region ' Barcodes '
      foreach (AcpBarcodeControl item in barcodes) {
        Image img = item.GetBarcodeImage(item.BarcodeText);
        if (img != null) {
          float h = scale * item.Size.Height;
          float w = scale * item.Size.Width;
          float x = (ml + dx) + scale * item.Location.X;
          float y = (mt + dy) + scale * item.Location.Y;
          G.DrawImage(img, x, y, w, h);
        }
      }
      #endregion
      labelQtyPrinted++;
      if (labelQtyPrinted == PrintPreview.Document.PrinterSettings.Copies) {
        e.HasMorePages = false;
        return;
      }
    }
    e.HasMorePages = (labelQtyPrinted < PrintPreview.Document.PrinterSettings.Copies);
  }
}

Overall, it works very well. Exclude "Run Away Printer" .

So why are so many copies made?

HP LaserJet 4050, .

+3
1

!

Yippie!

, - , : (2) .

, , .

labelsRequested labelQtyPrinted labelsPrinted:

private int labelsPrinted;
private int labelsRequested;

Print :

public int Print(string docName, int rows, int columns, int copies) {
  LabelsHorizontal = rows;
  LabelsVertical = columns;
  if (!String.IsNullOrEmpty(docName)) {
    PrintPreview.Document.DocumentName = docName;
  }
  labelsRequested = copies;
  //PrintPreview.Document.PrinterSettings.Copies = (short)copies;
  PrintPreview.SettingsFilename = Settings.PageSettingsLocation;
  if (!PrintPreview.PrinterSelected) {
    if (PrintPreview.ShowPrinterSelectDialog() != DialogResult.OK) {
      return 0;
    }
  }
  if (ShowPrintPreview) {
    Size docSize = PrintPreview.Document.DefaultPageSettings.Bounds.Size;
    float height = 0.8F * Screen.PrimaryScreen.WorkingArea.Size.Height;
    float width = (height * docSize.Width) / docSize.Height;
    Size winSize = new Size((int)width, (int)height);
    PrintPreview.Height = winSize.Height;
    PrintPreview.Width = winSize.Width;
    PrintPreview.Document.PrinterSettings.Copies = (short)labelsRequested; // this may cause problems
    PrintPreview.ShowDialog();
  } else {
    PrintPreview.PrintDocument();
  }
  return labelsPrinted;
}

print_Click, , Document BeginPrint EndPrint :

void Document_BeginPrint(object sender, PrintEventArgs e) {
  labelsPrinted = 0;
  float fPerPage = LabelsHorizontal * LabelsVertical;
  if (1 < fPerPage) {
    float fQty = labelsRequested;
    float fTotal = fQty / fPerPage;
    PrintPreview.Document.PrinterSettings.Copies = (short)fTotal;
  }
}

void Document_EndPrint(object sender, PrintEventArgs e) {
  Printed = (labelsPrinted == labelsRequested);
}

, , -, , HasMorePages PrintPage.

"?" . 1 . , , HasMorePages.

, PrintPage ( , ):

private void Document_Printed(object sender, PrintPageEventArgs e) {
  float scale;
  SizeF pageSize = new SizeF(
    PrintPreview.Document.DefaultPageSettings.PaperSize.Width,
    PrintPreview.Document.DefaultPageSettings.PaperSize.Height
  );
  Margins m = PrintPreview.Document.DefaultPageSettings.Margins;
  float printableHeight = pageSize.Height - (m.Top + m.Bottom);
  float printableWidth = pageSize.Width - (m.Left + m.Right);
  if (printableWidth < printableHeight) {
    if (labelSize.Width < labelSize.Height) {
      float r1 = printableWidth / labelSize.Width;
      float r2 = printableHeight / labelSize.Height;
      scale = (r1 < r2) ? r1 : r2;
    } else {
      scale = printableWidth / labelSize.Width;
    }
  } else {
    if (labelSize.Width < labelSize.Height) {
      scale = (printableHeight) / labelSize.Height;
    } else {
      float r1 = printableWidth / labelSize.Width;
      float r2 = printableHeight / labelSize.Height;
      scale = (r1 < r2) ? r1 : r2;
    }
  }
  float lh = scale * labelSize.Height;
  float lw = scale * labelSize.Width;
  float ml = scale * m.Left;
  float mt = scale * m.Top;
  Graphics G = e.Graphics;
  G.SmoothingMode = smoothMode;
  G.TextRenderingHint = TextRenderingHint.AntiAlias;
  for (int i = 0; (i < LabelsHorizontal) && !e.Cancel; i++) {
    float dx = i * (lw + ml); // Horizontal shift * scale
    for (int j = 0; (j < LabelsVertical) && !e.Cancel; j++) {
      float dy = j * (lh + mt); // Vertical shift * scale
      #region ' Panels '
      foreach (Panel item in panels) {
        float h = scale * item.Size.Height;
        float w = scale * item.Size.Width;
        float x = (ml + dx) + scale * item.Location.X;
        float y = (mt + dy) + scale * item.Location.Y;
        using (SolidBrush b = new SolidBrush(item.BackColor)) {
          G.FillRectangle(b, x, y, w, h);
        }
        using (Pen p = new Pen(Brushes.Black)) {
          G.DrawRectangle(p, x, y, w, h);
        }
      }
      #endregion
      #region ' Logo '
      if (logo != null) {
        float h = scale * logo.Height;
        float w = scale * logo.Width;
        float x = (ml + dx) + scale * logoPt.X;
        float y = (mt + dy) + scale * logoPt.Y;
        G.DrawImage(logo, x, y, w, h);
      }
      #endregion
      #region ' Labels '
      foreach (Label item in labels) {
        float h = scale * item.Size.Height;
        float w = scale * item.Size.Width;
        float x = (ml + dx) + scale * item.Location.X;
        float y = (mt + dy) + scale * item.Location.Y;
        Color c = PrintPreview.Document.DefaultPageSettings.Color ? item.ForeColor : Color.Black;
        Font font = new Font(item.Font.FontFamily, scale * item.Font.Size, item.Font.Style);
        using (SolidBrush b = new SolidBrush(c)) {
          StringFormat format = GetStringFormatFromContentAllignment(item.TextAlign);
          format.FormatFlags = StringFormatFlags.NoClip | StringFormatFlags.NoWrap;
          format.Trimming = StringTrimming.None;
          PointF locationF = new PointF(x, y);
          SizeF size = new SizeF(w, h);
          RectangleF r = new RectangleF(locationF, size);
          G.DrawString(item.Text, font, b, r, format);
        }
      }
      #endregion
      #region ' Barcodes '
      foreach (AcpBarcodeControl item in barcodes) {
        Image img = item.GetBarcodeImage(item.BarcodeText);
        if (img != null) {
          float h = scale * item.Size.Height;
          float w = scale * item.Size.Width;
          float x = (ml + dx) + scale * item.Location.X;
          float y = (mt + dy) + scale * item.Location.Y;
          G.DrawImage(img, x, y, w, h);
        }
      }
      #endregion
      labelsPrinted++;
    }
  }
}
+3

Source: https://habr.com/ru/post/1759037/