C#中PrintDocument_PrintPage方法重复打印问题求助
解决C# PrintDocument重复打印及分页排版问题
问题根源分析
- 重复打印:每次点击打印按钮时重复注册
PrintPage事件,导致打印触发多次事件处理器 - 行重叠:坐标计算中
j和a变量叠加逻辑混乱,导致每条记录的垂直位置计算错误 - 分页失效:
satir变量未初始化,循环起始/终止条件错误,分页判断逻辑不严谨
修复方案及代码实现
关键修复点:
- 将
PrintPage事件注册移至窗体初始化阶段,避免重复绑定 - 用全局变量记录当前打印的记录索引,确保分页时连续打印
- 简化垂直位置计算,每条记录占用固定高度
- 每页固定打印7条记录,打印完成后正确设置
HasMorePages状态 - 释放GDI资源(Font、Brush、Pen),避免内存泄漏
完整修复代码:
// 全局变量:记录当前打印到第几条数据,以及总记录数 private int _currentRowIndex = 0; private int _totalRows = 0; // 每页打印的记录数 private const int ROWS_PER_PAGE = 7; private void Form_Load(object sender, EventArgs e) { // 只注册一次PrintPage事件,避免重复绑定 printDocument1.PrintPage += printDocument1_PrintPage; printDocument1.DocumentName = "DataGridView Print"; printDocument1.DefaultPageSettings.Landscape = false; } private void button2_Click(object sender, EventArgs e) { // 每次打印前重置起始索引和总记录数 _currentRowIndex = 0; _totalRows = dataGridView1.Rows.Count; PrintPreviewDialog printPreviewDialog = new PrintPreviewDialog(); printPreviewDialog.Document = printDocument1; printPreviewDialog.ShowDialog(); } private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e) { // 字体和绘图资源定义,使用using自动释放 using (Font yazi_tip = new Font("Arial", 14)) using (SolidBrush kalem = new SolidBrush(Color.Black)) using (Pen kalems = new Pen(Color.Black)) { int rowsPrinted = 0; // 当前页的垂直起始位置 int yPos = 120; // 每条记录的高度(4行文本+1条分隔线) int rowHeight = 120; // 打印当前页的记录,直到满7条或打印完所有数据 while (rowsPrinted < ROWS_PER_PAGE && _currentRowIndex < _totalRows) { DataGridViewRow currentRow = dataGridView1.Rows[_currentRowIndex]; // 打印当前记录的各个字段 e.Graphics.DrawString(currentRow.Cells[2].Value.ToString(), yazi_tip, kalem, 40, yPos); e.Graphics.DrawString(currentRow.Cells[4].Value.ToString(), yazi_tip, kalem, 40, yPos + 30); e.Graphics.DrawString(currentRow.Cells[0].Value.ToString(), yazi_tip, kalem, 40, yPos + 60); e.Graphics.DrawString(currentRow.Cells[3].Value.ToString(), yazi_tip, kalem, 450, yPos); e.Graphics.DrawString(currentRow.Cells[5].Value.ToString(), yazi_tip, kalem, 450, yPos + 30); // 绘制分隔线 Point[] points = { new Point(50, yPos + 90), new Point(780, yPos + 90) }; e.Graphics.DrawLines(kalems, points); // 更新计数和位置 rowsPrinted++; _currentRowIndex++; yPos += rowHeight; } // 打印页码 int pageNumber = (_currentRowIndex - 1) / ROWS_PER_PAGE + 1; e.Graphics.DrawString($"Sayfa {pageNumber}", yazi_tip, kalem, 750, 1130); // 判断是否还有更多页需要打印 e.HasMorePages = _currentRowIndex < _totalRows; } }
代码说明:
- 事件注册优化:只在窗体加载时注册一次
PrintPage事件,彻底解决重复打印问题 - 分页逻辑:用
_currentRowIndex跟踪当前打印位置,每页打印7条后自动触发下一页 - 坐标计算:固定每条记录的高度和起始位置,避免行重叠
- 资源管理:使用
using语句自动释放GDI资源,防止内存泄漏
内容的提问来源于stack exchange,提问作者Ahmed Akpolat
相关产品推荐
相关产品推荐

