多页打印的事件处理实现求助(当前采用CopyFromScreen方法)
多页打印实现方案(替代CopyFromScreen方式)
原代码仅通过CopyFromScreen()捕获当前屏幕区域,只能实现单页打印。要支持多页,需要处理内容分页逻辑和逐页打印控制,以下是具体实现:
核心思路
- 摒弃屏幕捕获依赖:直接绘制控件内容(比抓屏幕更稳定,不受窗口显示状态影响)
- 计算分页:根据纸张尺寸和内容总高度,确定需要打印的页数
- 逐页打印:在
PrintPage事件中绘制当前页内容,通过HasMorePages标记是否还有下一页
修改后的完整代码
public partial class PrintForm : Form { // 当前打印页码 private int _currentPage = 0; // 内容总高度(假设内容在panelContent控件中) private int _totalContentHeight; private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e) { // 获取纸张可打印区域高度(扣除边距) var printAreaHeight = e.MarginBounds.Height; // 当前页内容起始Y坐标 int startY = _currentPage * printAreaHeight; // 超出内容总高度则停止打印 if (startY >= _totalContentHeight) { e.HasMorePages = false; _currentPage = 0; // 重置页码,方便下次打印 return; } // 当前页需要绘制的内容高度(最后一页可能不足整页) int drawHeight = Math.Min(printAreaHeight, _totalContentHeight - startY); // 定义内容来源区域和打印目标区域 Rectangle sourceRect = new Rectangle(0, startY, panelContent.Width, drawHeight); Rectangle destRect = new Rectangle(e.MarginBounds.X, e.MarginBounds.Y, panelContent.Width, drawHeight); // 绘制当前页内容(替代屏幕捕获) e.Graphics.DrawImage(GetFullControlImage(panelContent), destRect, sourceRect, GraphicsUnit.Pixel); // 判断是否还有下一页 e.HasMorePages = (startY + drawHeight) < _totalContentHeight; if (e.HasMorePages) _currentPage++; else _currentPage = 0; } // 获取控件完整内容图像(含滚动隐藏区域) private Bitmap GetFullControlImage(Control control) { Bitmap bitmap = new Bitmap(control.Width, control.Height); using (Graphics g = Graphics.FromImage(bitmap)) { control.DrawToBitmap(bitmap, new Rectangle(0, 0, control.Width, control.Height)); } return bitmap; } private void printbtn_Click(object sender, EventArgs e) { // 设置标准A4纸张尺寸(单位:百分之一英寸) printDocument1.DefaultPageSettings.PaperSize = new System.Drawing.Printing.PaperSize("A4", 827, 1169); // 设置打印边距 printDocument1.DefaultPageSettings.Margins = new System.Drawing.Printing.Margins(50, 50, 50, 50); // 初始化打印参数 _totalContentHeight = panelContent.Height; _currentPage = 0; printPreviewDialog1.Document = printDocument1; printPreviewDialog1.ShowDialog(); } }
关键说明
- 替代屏幕捕获:用
Control.DrawToBitmap()直接绘制控件全部内容,即使控件部分内容被滚动隐藏也能完整捕获,比CopyFromScreen()更可靠。 - 分页控制:通过
_currentPage记录当前页码,计算每一页的内容起始位置,用HasMorePages告诉打印系统是否需要继续打印下一页。 - 适配不同内容载体:如果内容在
TextBox或DataGridView中,只需调整_totalContentHeight的计算方式:- TextBox:
_totalContentHeight = textBox1.GetLineFromCharIndex(textBox1.TextLength) * textBox1.Font.Height; - DataGridView:
_totalContentHeight = dataGridView1.RowTemplate.Height * dataGridView1.RowCount + dataGridView1.ColumnHeadersHeight;
- TextBox:
内容的提问来源于stack exchange,提问作者Pradeep
相关产品推荐
相关产品推荐

