VB.NET 2022 PrintDocument在Win10与Win11的打印适配问题求助
VB.NET打印布局在Windows 10/11下不一致的解决求助
我在Windows 10平台用VB.NET 2022编写了打印功能代码,制作安装包部署到Windows 11后,应用运行正常,但打印文档的效果和Windows 10上不一致。调整adjustDGVtoA4的参数为Dim adjustDGVtoA4 As New Rectangle(60, 300, e.PageBounds.Width - 120, e.PageBounds.Height - 600)后,Windows 11的打印恢复正常,但Windows 10的打印又出现异常,求可行的解决建议。
原打印代码
Private Sub PrintDocument2_PrintPage(sender As Object, e As Printing.PrintPageEventArgs) Handles PrintDocument2.PrintPage Dim adjustToA4 As New Rectangle(0, 0, e.PageBounds.Width, e.PageBounds.Height) Dim adjustDGVtoA4 As New Rectangle(5, 300, e.PageBounds.Width - 10, e.PageBounds.Height - 600) Dim dm As New Bitmap(Panel1.Width, Panel1.Height) Panel1.DrawToBitmap(dm, New Rectangle(0, 0, Panel1.Width, Panel1.Height)) e.Graphics.DrawImage(dm, adjustToA4) Dim dgv As New Bitmap(DataGridView1.Width, DataGridView1.Height) DataGridView1.DrawToBitmap(dgv, New Rectangle(0, 0, DataGridView1.Width, DataGridView1.Height)) e.Graphics.DrawImage(dgv, adjustDGVtoA4) End Sub
打印效果对比
- 修改前Windows 10打印效果:

- 修改前Windows 11打印效果:

- 修改后Windows 10打印效果:

可行解决建议
1. 适配系统DPI差异
Windows 10和11的默认DPI缩放规则存在差异,e.PageBounds的实际像素值会受系统DPI影响。可以通过打印上下文的DPI值动态计算布局参数,避免硬编码像素:
Dim printDpiX As Single = e.Graphics.DpiX Dim printDpiY As Single = e.Graphics.DpiY ' 按英寸定义边距,换算为对应DPI下的像素值 Dim leftMargin As Integer = CInt(0.1 * printDpiX) ' 0.1英寸左边距 Dim topMargin As Integer = CInt(5 * printDpiX) ' 对应原300像素的顶部位置,按比例换算 Dim adjustDGVtoA4 As New Rectangle(leftMargin, topMargin, e.PageBounds.Width - 2 * leftMargin, e.PageBounds.Height - 2 * topMargin)
2. 检测系统版本动态调整参数
通过判断当前运行的Windows版本,加载对应的布局参数,适配不同系统的渲染差异:
Dim osVersion As Version = Environment.OSVersion.Version ' Windows 11的Build版本从22000开始 Dim isWin11OrLater As Boolean = osVersion.Major >= 10 AndAlso osVersion.Build >= 22000 Dim dgvRect As Rectangle If isWin11OrLater Then dgvRect = New Rectangle(60, 300, e.PageBounds.Width - 120, e.PageBounds.Height - 600) Else dgvRect = New Rectangle(5, 300, e.PageBounds.Width - 10, e.PageBounds.Height - 600) End If ' 后续使用dgvRect绘制DGV
3. 替代DrawToBitmap,直接绘制DataGridView内容
DrawToBitmap在不同系统下的渲染行为可能不一致,建议直接遍历DataGridView的行和列,用e.Graphics手动绘制单元格内容与边框,完全控制打印布局:
' 绘制表头 Dim headerY As Integer = 300 For Each col As DataGridViewColumn In DataGridView1.Columns e.Graphics.DrawString(col.HeaderText, DataGridView1.Font, Brushes.Black, col.HeaderCell.ContentBounds.X + 5, headerY) e.Graphics.DrawRectangle(Pens.Black, col.HeaderCell.ContentBounds.X, headerY, col.Width, DataGridView1.RowTemplate.Height) Next ' 绘制行内容 Dim rowY As Integer = headerY + DataGridView1.RowTemplate.Height For Each row As DataGridViewRow In DataGridView1.Rows For Each cell As DataGridViewCell In row.Cells If cell.Value IsNot Nothing Then e.Graphics.DrawString(cell.Value.ToString(), DataGridView1.Font, Brushes.Black, cell.ContentBounds.X + 5, rowY) End If e.Graphics.DrawRectangle(Pens.Black, cell.ContentBounds.X, rowY, cell.OwningColumn.Width, row.Height) Next rowY += row.Height Next
4. 提升图形渲染质量
调整e.Graphics的渲染模式,减少不同系统下的缩放差异:
e.Graphics.InterpolationMode = Drawing.Drawing2D.InterpolationMode.HighQualityBicubic e.Graphics.SmoothingMode = Drawing.Drawing2D.SmoothingMode.HighQuality e.Graphics.PixelOffsetMode = Drawing.Drawing2D.PixelOffsetMode.HighQuality
内容的提问来源于stack exchange,提问作者zeak
相关产品推荐
相关产品推荐

