Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/extjs/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# PrintPage PrintPageEventHandler打印的副本太多_C#_Winforms_Printing - Fatal编程技术网

C# PrintPage PrintPageEventHandler打印的副本太多

C# PrintPage PrintPageEventHandler打印的副本太多,c#,winforms,printing,C#,Winforms,Printing,我必须为我们公司生产的产品打印装运标签 为了帮助自己了解这些标签的效果,我使用Windows窗体设计了它们。这使我能够定位文本,正确设置字体等。使用标签控件,添加自定义条形码控件,并使用面板控件将项目分组到框中 每页有两(2)个标签 当我的代码打印标签文档时,我请求2、4或6份副本。偶尔也会使用打印预览。在这种情况下,我必须重置创建的标签数量 但是,当文档打印时: 如果请求2份,代码将打印2张纸(4个标签) 如果请求4份,代码将打印8张纸(16个标签) 如果请求6份,代码将打印多达18页(36

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

为了帮助自己了解这些标签的效果,我使用Windows窗体设计了它们。这使我能够定位文本,正确设置字体等。使用
标签
控件,添加自定义
条形码
控件,并使用
面板
控件将项目分组到框中

每页有两(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\u Click方法覆盖它的打印按钮:

// 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\u 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);
  }
}
private void Document\u打印(对象发送者,PrintPageEventArgs e){

如果(PrintPreview.Document.PrinterSettings.Copies)我知道了

哎呀

好吧,如果有人在乎的话,这里有个交易:我需要每页打印两(2)个标签

我要做的是计算要打印多少页,使用垂直和水平打印的标签数量

我添加了变量
labelsRequested
,并将现有变量
labelQtyPrinted
更改为
labelsPrinted

private int labelsPrinted;
private int labelsRequested;
我的public
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\u Click
事件处理程序,而是将
文档的
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);
}

@约翰·桑德斯:为什么你要从我的标题中去掉
C
?因为你应该使用标签而不是标题来更好地识别(分类)你的问题。See@Steve是对的。我通常不会向1000个或更多代表的用户讲解这一点,但标记是标记的位置,而不是标题。通过实现PrintDocument.BeginPrint事件的处理程序来重置页面计数器。使用调试器查看计数的情况。将退出条件放在for循环中看起来非常简单ishy。我猜打印方式可能会超过页面的结尾,打印机驱动程序会将其拆分为多个页面。@nobugs:当我在电脑上测试时(使用Adobe PDF的Windows 7),正确的打印页数。
BeginPrint
有一个例程可以将计数设置为零,
EndPrint
有一个例程可以设置
AllPrinted=(labelQtyPrinted==PrintPreview.Document.PrinterSettings.Copies)
这怎么会没有更多的投票?当我找到这个时,我正在寻求帮助做同样的事情。谢谢!!!谢谢,@dev_JORD。我很高兴其他人从中得到了一些帮助!
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++;
    }
  }
}