C#打印多页异常:重复写入首页而非生成新页
解决C# PrintDocument多页打印内容重叠问题
核心问题是每次点击打印按钮时重复绑定了PrintPage事件,导致HasMorePages触发后,多个事件处理实例同时执行,内容叠加到同一页面上。另外代码中存在字体资源未释放的潜在问题,以下是具体修复方案:
1. 移除重复的事件绑定
将PrintPage事件的注册移到窗体构造函数(或初始化逻辑)中,不要在打印按钮点击事件里重复添加。重复绑定会导致每次触发PrintPage时,多个处理程序同时运行,最终内容重叠在同一页。
2. 确保打印状态正确重置
每次打印开始时,正确重置rowIndexForPrinting和page变量,避免上次打印的状态干扰当前打印流程。
3. 释放字体资源(推荐)
Font实现了IDisposable接口,使用using语句包裹,避免内存泄漏。
修改后的完整代码示例
List<List<string>> sifirlamaPrintList; // 存储要打印的数据 int rowIndexForPrinting; int page; // 窗体构造函数 public YourFormName() { InitializeComponent(); // 仅绑定一次PrintPage事件 printDocumentSifirlama.PrintPage += printDocumentSifirlama_PrintPage; } private void printSifirlama_Click(object sender, EventArgs e) { PrintListCreation(); // 获取待打印数据 rowIndexForPrinting = 0; page = 1; PrintDialog printDialog = new PrintDialog(); printDocumentSifirlama.DefaultPageSettings.Landscape = true; if (printDialog.ShowDialog() == DialogResult.OK) { printDocumentSifirlama.PrinterSettings = printDialog.PrinterSettings; printDocumentSifirlama.DefaultPageSettings.Landscape = true; printDocumentSifirlama.Print(); } } private void printDocumentSifirlama_PrintPage(object sender, PrintPageEventArgs e) { float x = e.MarginBounds.Left; float y = e.MarginBounds.Top; float headerHeight = 60; // 表头行高度 int dataCellHeight = 45; // 数据行高度 List<int> columnWidths = new List<int>() { 50, 50, 50, 100, 175, 100, 175, 250, 75 }; List<string> columnHeadersList = new List<string>() { "Id", "GNo", "UNo", "Rtb", "Name", "Rtb", "Ad Soyad", "Unit", "Row" }; // 自动释放表头字体资源 using (Font headerFont = new Font("Arial", 10, FontStyle.Bold)) { for (int i = 0; i < 9; i++) { RectangleF cellRect = new RectangleF(x, y, columnWidths[i], headerHeight); e.Graphics.DrawRectangle(Pens.Black, Rectangle.Round(cellRect)); e.Graphics.DrawString(columnHeadersList[i], headerFont, Brushes.Black, cellRect, new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center }); x += columnWidths[i]; } } y += headerHeight; // 自动释放数据行字体资源 using (Font dataFont = new Font("Arial", 10)) { while (rowIndexForPrinting < sifirlamaPrintList.Count) { x = e.MarginBounds.Left; for (int i = 0; i < sifirlamaPrintList[rowIndexForPrinting].Count; i++) { RectangleF cellRect = new RectangleF(x, y, columnWidths[i], dataCellHeight); e.Graphics.DrawRectangle(Pens.Black, Rectangle.Round(cellRect)); e.Graphics.DrawString(sifirlamaPrintList[rowIndexForPrinting][i], dataFont, Brushes.Black, cellRect, new StringFormat { Alignment = StringAlignment.Center, LineAlignment = StringAlignment.Center }); x += columnWidths[i]; } y += dataCellHeight; rowIndexForPrinting++; if (y + dataCellHeight > e.MarginBounds.Bottom) { e.HasMorePages = true; page++; return; } } } e.HasMorePages = false; }
关键修改说明
- 事件绑定移到构造函数,确保仅注册一次,避免多实例执行导致内容重叠。
- 使用
using语句管理字体资源,自动释放内存。 - 保留原有分页逻辑,确保
rowIndexForPrinting跨页面正确累加,实现多页连续打印。
内容的提问来源于stack exchange,提问作者Mat
相关产品推荐
相关产品推荐

