You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#中PrintDocument_PrintPage方法重复打印问题求助

解决C# PrintDocument重复打印及分页排版问题

问题根源分析

  1. 重复打印:每次点击打印按钮时重复注册PrintPage事件,导致打印触发多次事件处理器
  2. 行重叠:坐标计算中j和a变量叠加逻辑混乱,导致每条记录的垂直位置计算错误
  3. 分页失效: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;
    }
}

代码说明:

  1. 事件注册优化:只在窗体加载时注册一次PrintPage事件,彻底解决重复打印问题
  2. 分页逻辑:用_currentRowIndex跟踪当前打印位置,每页打印7条后自动触发下一页
  3. 坐标计算:固定每条记录的高度和起始位置,避免行重叠
  4. 资源管理:使用using语句自动释放GDI资源,防止内存泄漏

内容的提问来源于stack exchange,提问作者Ahmed Akpolat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.27 22:32:50