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

VB.NET中DataGridView表头预览可见但打印消失问题求助

解决VB.NET PrintDocument打印DataGridView表头预览可见但实际打印消失的问题

问题根源

你的代码存在三个核心问题:

  1. 未在打印开始时重置mRow和newPage的状态,导致实际打印时newPage可能未被设为True,第一页表头无法绘制;
  2. 未处理多页打印的状态传递,后续页面不会触发表头绘制;
  3. 打印单元格内容时修改了全局的StringFormat对齐方式,会影响表头的居中绘制效果。

修复方案

1. 声明类级变量

确保mRow和newPage是窗体/类的成员变量(不是局部变量):

Private mRow As Integer = 0
Private newPage As Boolean = True

2. 添加BeginPrint事件处理

在打印开始时重置状态,保证每次打印/预览都从头开始,第一页会绘制表头:

Private Sub PrintDocument1_BeginPrint(sender As Object, e As Printing.PrintEventArgs) Handles PrintDocument1.BeginPrint
    mRow = 0
    newPage = True
End Sub

3. 修改PrintPage事件代码

修复多页逻辑、避免StringFormat污染:

Private Sub PrintDocument1_PrintPage(sender As Object, e As Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
    Dim format As New StringFormat
    format.Alignment = StringAlignment.Center
    e.Graphics.DrawString("PULL OUT", New Font("Century Gothic", 25, FontStyle.Bold), Brushes.Black, New Point(400, 20), format)

    ' 用于表头的StringFormat,保持居中
    Dim headerFmt As New StringFormat(StringFormatFlags.LineLimit)
    headerFmt.LineAlignment = StringAlignment.Center
    headerFmt.Trimming = StringTrimming.EllipsisCharacter
    headerFmt.Alignment = StringAlignment.Center

    ' 用于单元格内容的StringFormat,单独创建避免污染表头格式
    Dim cellFmt As New StringFormat(StringFormatFlags.LineLimit)
    cellFmt.LineAlignment = StringAlignment.Center
    cellFmt.Trimming = StringTrimming.EllipsisCharacter
    cellFmt.Alignment = StringAlignment.Near

    Dim y As Integer = 100
    Dim x As Integer = 100
    Dim h As Integer = 0
    Dim rc As Rectangle
    Dim row As DataGridViewRow

    ' 绘制表头
    If newPage Then
        ' 使用列集合直接绘制表头,逻辑更清晰
        For Each col As DataGridViewColumn In DataGridView1.Columns
            If col.Visible Then
                rc = New Rectangle(x, y, col.Width, DataGridView1.ColumnHeadersHeight)
                e.Graphics.FillRectangle(Brushes.LightGray, rc)
                e.Graphics.DrawRectangle(Pens.Black, rc)
                e.Graphics.DrawString(col.HeaderText, DataGridView1.Font, Brushes.Black, rc, headerFmt)
                x += rc.Width
                h = Math.Max(h, rc.Height)
            End If
        Next
        y += h
    End If

    newPage = False
    Dim displayNow As Integer
    For displayNow = mRow To DataGridView1.RowCount - 1
        row = DataGridView1.Rows(displayNow)
        x = 100
        h = 0

        ' 绘制行内容
        For Each cell As DataGridViewCell In row.Cells
            If cell.Visible Then
                rc = New Rectangle(x, y, cell.Size.Width, cell.Size.Height)
                e.Graphics.DrawRectangle(Pens.Black, rc)
                
                ' 使用单独的cellFmt,不修改表头的格式
                rc.Offset(10, 0)
                e.Graphics.DrawString(cell.FormattedValue.ToString, DataGridView1.Font, Brushes.Black, rc, cellFmt)

                x += rc.Width
                h = Math.Max(h, rc.Height)
            End If
        Next
        y += h

        ' 判断是否超出页面边界,准备下一页
        If y + h > e.MarginBounds.Bottom Then
            mRow = displayNow + 1
            newPage = True
            e.HasMorePages = True
            Return
        End If
    Next

    ' 所有行打印完成,重置状态
    e.HasMorePages = False
    mRow = 0
    newPage = True
End Sub

关键修改说明

  • 分离StringFormat:表头和单元格内容使用各自的StringFormat,避免修改对齐方式后互相影响;
  • BeginPrint初始化:每次打印开始时重置mRow和newPage,确保第一页一定会绘制表头;
  • 多页判断:在打印每行后检查是否超出页边距,设置e.HasMorePages = True并更新状态,让下一页自动触发表头绘制;
  • 表头绘制优化:直接遍历DataGridView.Columns获取表头文本和宽度,不需要依赖行单元格,逻辑更稳定。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 11:17:35