这段代码出了什么问题?它没有显示PrintPreview中的第一行

时间:2015-05-07 05:47:03

标签: vb.net print-preview

下面的代码实际上是从其中一个stackoverflow答案中复制过来的,它没有显示打印预览中的第一行。它跳过第一排,从第二排开始。

这是代码,

Dim mRow As Integer = 0
Dim newpage As Boolean = True
Private Sub PrintDocument1_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
    newpage = True
    With dgvData
        Dim fmt As StringFormat = New StringFormat(StringFormatFlags.LineLimit)
        'Dim fmt2 As StringFormat = New StringFormat(StringFormatFlags.LineLimit)
        fmt.LineAlignment = StringAlignment.Center
        'Dim font As Font

        'font = New Font("Microsoft Sans Serif", "13", FontStyle.Underline, GraphicsUnit.Inch, gdiCharSet:=1)
        'fmt.Trimming = StringTrimming.EllipsisCharacter
        Dim rc1 As RectangleF = New RectangleF(460, 20, 350, 20)
        Dim rc2 As RectangleF = New RectangleF(500, 40, 350, 20)

        e.Graphics.DrawString("Some Heading", .Font, Brushes.Black, rc1, fmt)
        e.Graphics.DrawString("Another heading ", .Font, Brushes.Black, rc2, fmt)

        Dim y As Single = e.MarginBounds.Top + 60
        Do While mRow < .RowCount
            Dim row As DataGridViewRow = .Rows(mRow)
            Dim x As Single = e.MarginBounds.Left
            Dim h As Single = 0
            For Each cell As DataGridViewCell In row.Cells
                Dim rc As RectangleF = New RectangleF(x, y, cell.Size.Width, cell.Size.Height)
                e.Graphics.DrawRectangle(Pens.Black, rc.Left, rc.Top, rc.Width, rc.Height)
                If (newpage) Then
                    e.Graphics.DrawString(dgvData.Columns(cell.ColumnIndex).HeaderText.ToString, .Font, Brushes.Black, rc, fmt)
                    'MessageBox.Show(dgvData.Columns(cell.ColumnIndex).HeaderText.ToString)
                Else
                    e.Graphics.DrawString(dgvData.Rows(cell.RowIndex).Cells(cell.ColumnIndex).FormattedValue.ToString(), .Font, Brushes.Black, rc, fmt)
                    'MessageBox.Show(dgvData.Rows(cell.RowIndex).ToString)
                End If
                x += rc.Width
                h = Math.Max(h, rc.Height)
            Next
            newpage = False
            y += h
            mRow += 1
            If y + h > e.MarginBounds.Bottom Then
                e.HasMorePages = True
                mRow -= 1
                newpage = True
                Exit Sub
            End If
        Loop
        mRow = 0
    End With
End Sub

1 个答案:

答案 0 :(得分:1)

[如果我正确理解了这一点,]它会跳过第一行,因为newpage设置为True,所以当你看到这段代码时:

If (newpage) Then
    e.Graphics.DrawString(dgvData.Columns(cell.ColumnIndex).HeaderText.ToString, .Font, Brushes.Black, rc, fmt)
    'MessageBox.Show(dgvData.Columns(cell.ColumnIndex).HeaderText.ToString)
Else
    e.Graphics.DrawString(dgvData.Rows(cell.RowIndex).Cells(cell.ColumnIndex).FormattedValue.ToString(), .Font, Brushes.Black, rc, fmt)
    'MessageBox.Show(dgvData.Rows(cell.RowIndex).ToString)
End If

您正在打印标题,而不是当前行(Dim row As DataGridViewRow = .Rows(mRow))中的单元格。

编辑以回应“所以我应该在开始时设置newage = false,还是我还应该做什么?

如果newpage的计算结果为True,则需要输出标题和当前行。在原始代码中,您使用If开关来执行一个或另一个(从而跳过当前行的输出)。我做了一些快速重组,下面是我的全新建议代码,所以你可以比较。

Dim mRow As Integer = 0
Dim newpage As Boolean = True
Private Sub PrintDocument1_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
    newpage = True
    With dgvData
        Dim fmt As StringFormat = New StringFormat(StringFormatFlags.LineLimit)
        'Dim fmt2 As StringFormat = New StringFormat(StringFormatFlags.LineLimit)
        fmt.LineAlignment = StringAlignment.Center
        'Dim font As Font

        'font = New Font("Microsoft Sans Serif", "13", FontStyle.Underline, GraphicsUnit.Inch, gdiCharSet:=1)
        'fmt.Trimming = StringTrimming.EllipsisCharacter
        Dim rc1 As RectangleF = New RectangleF(460, 20, 350, 20)
        Dim rc2 As RectangleF = New RectangleF(500, 40, 350, 20)

        e.Graphics.DrawString("Some Heading", .Font, Brushes.Black, rc1, fmt)
        e.Graphics.DrawString("Another heading ", .Font, Brushes.Black, rc2, fmt)

        Dim rc As RectangleF
        Dim y As Single = e.MarginBounds.Top + 60
        Do While mRow < .RowCount
            Dim row As DataGridViewRow = .Rows(mRow)
            Dim x As Single = e.MarginBounds.Left
            Dim h As Single = 0
            If (newpage) Then
                For Each cell As DataGridViewCell In row.Cells
                    rc = New RectangleF(x, y, cell.Size.Width, cell.Size.Height)
                    e.Graphics.DrawRectangle(Pens.Black, rc.Left, rc.Top, rc.Width, rc.Height)
                    e.Graphics.DrawString(dgvData.Columns(cell.ColumnIndex).HeaderText.ToString, .Font, Brushes.Black, rc, fmt)
                    'MessageBox.Show(dgvData.Columns(cell.ColumnIndex).HeaderText.ToString)
                    x += rc.Width
                    h = Math.Max(h, rc.Height)
                Next
                newpage = False
                y += h
                x = e.MarginBounds.Left
                h = 0
            End If
            For Each cell As DataGridViewCell In row.Cells
                rc = New RectangleF(x, y, cell.Size.Width, cell.Size.Height)
                e.Graphics.DrawRectangle(Pens.Black, rc.Left, rc.Top, rc.Width, rc.Height)
                e.Graphics.DrawString(dgvData.Rows(cell.RowIndex).Cells(cell.ColumnIndex).FormattedValue.ToString(), .Font, Brushes.Black, rc, fmt)
                'MessageBox.Show(dgvData.Rows(cell.RowIndex).ToString)
                x += rc.Width
                h = Math.Max(h, rc.Height)
            Next
            y += h
            mRow += 1
            If y + h > e.MarginBounds.Bottom Then
                e.HasMorePages = True
                mRow -= 1
                newpage = True
                Exit Sub
            End If
        Loop
        mRow = 0
    End With
End Sub

要注意的一些变化:

  • newpage开关与输出实际单元格的For Each隔离开来。无论newpage条件如何,都会导致输出当前行。
  • 某些变量(xhy)必须在交换机内部和外部递增或修改,因此这些行现在都是重复的。
  • rc的声明已移出Do While循环。没有必要为每个细胞声明它;而只是分配一个新值。
  • 真的没有必要多次检查y + h > e.MarginBounds.Bottom(除非你打印真的很大),因为如果你已经在顶部,你可以假设你只打印多行一个新页面,所以它在循环结束时保持不变。
  • 评估Math.Max(h, rc.Height)时,h始终为零或等于rc.Height,因此您可以考虑重新考虑此问题。