PrintPage PrintPageEventHandler打印太多副本

我必须为我们公司生产的产品打印运输标签。

为了让我自己了解这些标签的结果,我使用Windows窗体进行设计。 这允许我使用Label控件定位我的文本,设置正确的字体等,添加自定义BarCode控件,并使用Panel控件“ 花哨 ”将项目分组到框中。

每页包含两(2)个标签。

当我的代码打印标签文档时,我要求2,4或6份副本。 有时,也会使用“打印预览”。 在这种情况下,我必须重置创建的标签数量。

但是,当文件打印时:

  • 如果请求是2份,代码打印2张纸(4个标签)
  • 如果请求是4份,代码打印8张纸(16个标签)
  • 如果请求是6份,代码打印高达18页(36个标签)

有没有人看到一种模式? 我不。

这是我的打印命令:

 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; } 

我必须编写一个自定义的PrintPreview类,它将PrintPreviewDialog作为基类,以便我可以使用此printButton_Click方法覆盖其Print按钮:

 // 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(); } 

Print方法(第一个代码片段)中, PrintPreview.PrintDocument()只是调用printButton_Click事件的代码。

我的PrintPageEventHandler如下所示:

 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); } } 

总而言之,它运作良好。 永远不会抛出“Run Away Printer”exception。

那么,为什么要制作这么多的副本呢?

打印机是HP LaserJet 4050,如果这有任何区别的话。

我知道了!

开心辞典!

好吧,如果有人关心,这是交易:我需要每页打印两(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事件处理程序,而是连接了DocumentBeginPrintEndPrint如下所示:

 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); } 

但是,这里的关键显然来自于我试图在PrintPage事件处理程序中设置HasMorePages值。

“为什么?” 你问。 因为我只打印了相同的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++; } } }