在 C# WinForms 中使用 PrintDocument
打印时,如果遇到坐标或尺寸参数为负数的问题,通常会导致打印内容无法正常显示或抛出异常。以下是解决方案和注意事项:
1. 确保打印坐标/尺寸非负
PrintDocument
的打印区域(如 e.Graphics.DrawString
或 e.Graphics.DrawImage
)的坐标和宽高必须是非负数,否则可能引发异常。
示例代码:验证参数有效性
private void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
{
// 示例:打印文本(确保 X/Y ≥0)
string text = "Hello, World!";
Font font = new Font("Arial", 12);
Brush brush = Brushes.Black;
float x = 10; // X坐标必须 ≥0
float y = 10; // Y坐标必须 ≥0
if (x >= 0 && y >= 0)
{
e.Graphics.DrawString(text, font, brush, x, y);
}
else
{
MessageBox.Show("打印坐标不能为负数!");
}
}
2. 动态计算位置时的防护
如果通过计算得到打印位置(例如居中、偏移),需强制限制结果为非负数:
float CalculateSafeX(float desiredX)
{
return Math.Max(0, desiredX); // 确保返回值 ≥0
}
// 使用示例
float safeX = CalculateSafeX(-5); // 返回0
3. 处理页边距(Margins)
PrintDocument
的默认页边距可能导致内容被裁剪。可通过 PrintPageEventArgs.MarginBounds
获取安全区域:
private void printDocument1_PrintPage(object sender, PrintPageEventArgs e)
{
RectangleF marginBounds = e.MarginBounds; // 可打印区域(考虑页边距)
// 在安全区域内绘制内容
e.Graphics.DrawString(
"Printed within margins",
new Font("Arial", 12),
Brushes.Black,
marginBounds.Left, // X ≥ MarginBounds.Left
marginBounds.Top // Y ≥ MarginBounds.Top
);
}
4. DPI/缩放问题
高DPI设置可能导致坐标转换错误。可通过 Graphics.PageUnit
指定单位:
e.Graphics.PageUnit = GraphicsUnit.Display; // 使用像素单位避免缩放问题
5. Debugging Tips
- 检查所有硬编码值:确保没有直接传入负数。
- 日志输出:在计算坐标时输出日志: “`csharp Console.WriteLine($“Printing at X={x}, Y={y}”);
- **捕获异常**:
```csharp
try
{
printDocument1.Print();
}
catch (Exception ex)
{
MessageBox.Show($"打印失败: {ex.Message}");
}
常见错误场景
问题 | 原因 | 修复方法 |
---|---|---|
ArgumentOutOfRangeException |
X/Y或宽高为负数 | 用 Math.Max(0, value) 约束 |
内容偏移到页面外 | 未考虑页边距 | 使用 MarginBounds 作为基准区域 |
缩放后布局错乱 | DPI缩放导致坐标计算错误 | 设置 Graphics.PageUnit |
通过以上方法,可以确保打印内容的坐标和尺寸始终有效。
内容由零声教学AI助手提供,问题来源于学员提问