在 Windows 應用中,完整打印功能通常包含:
PrintDialog)PageSetupDialog)PrintPreviewDialog)PrintDocument.Print)System.Drawing.Printing.PrintDocument 封裝所有打印邏輯,關鍵成員:
| 成員 | 說明 |
|---|---|
| PrinterSettings | 打印機設置(由 PrintDialog 自動填充) |
| DefaultPageSettings | 頁面設置(由 PageSetupDialog 自動填充) |
| DocumentName | 顯示在打印隊列中的文檔名 |
| PrintPage 事件 | 核心繪制邏輯,每頁觸發一次 |
| BeginPrint/EndPrint 事件 | 打印開始/結束時觸發,可做初始化/清理 |
| Print() 方法 | 啟動打印流程 |
事件參數 PrintPageEventArgs 提供:
Graphics:頁面繪圖面MarginBounds:可打印區域(不含邊距)PageBounds:整頁物理大小HasMorePages:設置 true 觸發下一頁
private StringReader lineReader; // 類級字段,保持讀取位置
private void printDocument_PrintPage(object sender, PrintPageEventArgs e)
{
Graphics g = e.Graphics;
Font printFont = textBox.Font; // 要打印的字體
SolidBrush brush = new SolidBrush(Color.Black);
float linesPerPage = e.MarginBounds.Height / printFont.GetHeight(g);
float yPos = e.MarginBounds.Top;
int count = 0;
string line;
// 逐行打印當前頁
while (count < linesPerPage && ((line = lineReader.ReadLine()) != null))
{
yPos = e.MarginBounds.Top + count * printFont.GetHeight(g);
g.DrawString(line, printFont, brush, e.MarginBounds.Left, yPos);
count++;
}
// 還有內容則設置 HasMorePages=true,觸發下一次 PrintPage
e.HasMorePages = (line != null);
}
所有對話框均通過 Document 屬性關聯同一 PrintDocument 實例:
// 打印設置
private void MenuPrintSetup_Click(object sender, EventArgs e)
{
using (PrintDialog dlg = new PrintDialog { Document = printDocument })
dlg.ShowDialog();
}
// 頁面設置
private void MenuPageSetup_Click(object sender, EventArgs e)
{
using (PageSetupDialog dlg = new PageSetupDialog { Document = printDocument })
dlg.ShowDialog();
}
// 打印預覽
private void MenuPrintPreview_Click(object sender, EventArgs e)
{
lineReader = new StringReader(textBox.Text); // 重置讀取器
using (PrintPreviewDialog dlg = new PrintPreviewDialog { Document = printDocument })
{
try { dlg.ShowDialog(); }
catch (Exception ex) { MessageBox.Show(ex.Message, "預覽錯誤"); }
}
}
// 正式打印
private void MenuPrint_Click(object sender, EventArgs e)
{
lineReader = new StringReader(textBox.Text);
using (PrintDialog dlg = new PrintDialog { Document = printDocument })
{
if (dlg.ShowDialog() == DialogResult.OK)
{
try { printDocument.Print(); }
catch (Exception ex) { MessageBox.Show(ex.Message, "打印錯誤"); }
}
}
}
g.DrawImage(image, rect),注意縮放比例與分頁DrawRectangle+DrawStringReportViewer (RDLC) 或第三方庫 (FastReport, Stimulsoft)PrintDocument.Print 是同步阻塞的。大文檔建議:
PrintPrintPage 事件報告進度(當前頁/總頁數)e.Cancel = true)MarginBounds 單位為 1/100 英寸,與 Graphics 默認單位 (1/100 英寸) 一致lineReader 在預覽和打印前均重置Invoke掌握 PrintDocument + PrintPage 事件驅動模型,配合三大對話框,即可實現專業級打印功能。關鍵在於正確處理分頁邏輯(HasMorePages)、資源管理(using 釋放筆刷/字體)與異常捕獲。複雜排版場景請引入專業報表組件。