如何在 vb.net 中打印带有标题的 datagridview 表? [英] How to print datagridview table with its header in vb.net?

查看:42
本文介绍了如何在 vb.net 中打印带有标题的 datagridview 表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发的系统中创建打印预览功能,该功能将预览我想要打印的数据网格视图.我使用 ooopsoft 的

在您可以看到序列号为 1 的 dgv 行丢失了.看起来标题已经覆盖了第一行.我尝试了无数方法来解决它,但我仍然找不到解决方案.我尝试退出打印预览对话框并再次打开它,但是

请注意,DGV 中有一个 Id 列设置为不可见,Color 列居中,Price 左对齐 - 这些都是从控件中获取的设置.另请注意,文本稍微远离网格线.

<小时>

上面的最后一个要点,您还需要在按钮单击或 BeginPrint 事件中重置 mRownewpage. 意思是:

Private Sub PrintDocument1_BeginPrint(sender As Object,e As PrintEventArgs) 处理 PrintDocument1.BeginPrint行 = 0新页面 = 真PrintPreviewDialog1.PrintPreviewControl.StartPage = 0PrintPreviewDialog1.PrintPreviewControl.Zoom = 1.0结束子

预览后 mRow 变量将指示所有行都已打印.如果用户单击打印或返回另一个预览,则不会打印任何内容.此代码还会重置要显示的第一页和初始缩放.

I'm creating a print preview function in a system that I'm developing which will preview the datagridview that I want to print. I used ooopsoft's codes as reference and it works fine except for a slight problem.

Problem:

In the you can see that the dgv row with serial number 1 is missing. It appears the header has overwritten the 1st row. I have tried a myriad of ways to solve it, but I still can't find the solution. I tried exiting the print preview dialog and opening it again, but this is the result I got. I think I'm missing a line of code, but I can't figure out what. Please help.

解决方案

The original code is a nice start but has a couple of bugs and inefficiecies:

  • It uses the newpage flag to print the header or the first row when there is a new page. Obviously you really want it to do both
  • Printing the column headers is done once per page, so it doesnt need to be in the data print loop at all
  • It is not allowing for invisible columns or columns with other than default alignment, There could be other such settings you want to account for.
  • Because it is not actually printing the correct number of rows, once you fix that you'll find that it reprints the last row from the previous page as the first row of a new page.
  • There is an internal gutter or margin so that text does not print too close to gridlines - this just uses an offset of 1 or 2
  • It is also needlessly using single and RectangleF
  • It is also not prepared for the Document to be shown again or Printed. You will also want to reset mRow and newpage either in the button click or BeginPrint event.

I added a few comments as well as coloring the header row and demonstrating how to implement things like a RowPrePaint rule.

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

Private Sub PrintDocument1_PrintPage(sender As System.Object,
                    e As PrintPageEventArgs) Handles PrintDocument1.PrintPage

    ' sets it to show '...' for long text
    Dim fmt As StringFormat = New StringFormat(StringFormatFlags.LineLimit)
    fmt.LineAlignment = StringAlignment.Center
    fmt.Trimming = StringTrimming.EllipsisCharacter
    Dim y As Int32 = e.MarginBounds.Top
    Dim rc As Rectangle
    Dim x As Int32
    Dim h As Int32 = 0
    Dim row As DataGridViewRow

    ' print the header text for a new page
    '   use a grey bg just like the control
    If newpage Then
        row = dgvZZ.Rows(mRow)
        x = e.MarginBounds.Left
        For Each cell As DataGridViewCell In row.Cells
            ' since we are printing the control's view,
            ' skip invidible columns
            If cell.Visible Then
                rc = New Rectangle(x, y, cell.Size.Width, cell.Size.Height)

                e.Graphics.FillRectangle(Brushes.LightGray, rc)
                e.Graphics.DrawRectangle(Pens.Black, rc)

                ' reused in the data pront - should be a function
                Select Case dgvZZ.Columns(cell.ColumnIndex).DefaultCellStyle.Alignment
                    Case DataGridViewContentAlignment.BottomRight,
                         DataGridViewContentAlignment.MiddleRight
                        fmt.Alignment = StringAlignment.Far
                        rc.Offset(-1, 0)
                    Case DataGridViewContentAlignment.BottomCenter,
                        DataGridViewContentAlignment.MiddleCenter
                        fmt.Alignment = StringAlignment.Center
                    Case Else
                        fmt.Alignment = StringAlignment.Near
                        rc.Offset(2, 0)
                End Select

                e.Graphics.DrawString(dgvZZ.Columns(cell.ColumnIndex).HeaderText,
                                            dgvZZ.Font, Brushes.Black, rc, fmt)
                x += rc.Width
                h = Math.Max(h, rc.Height)
            End If
        Next
        y += h

    End If
    newpage = False

    ' now print the data for each row
    Dim thisNDX As Int32
    For thisNDX = mRow To dgvZZ.RowCount - 1
        ' no need to try to print the new row
        If dgvZZ.Rows(thisNDX).IsNewRow Then Exit For

        row = dgvZZ.Rows(thisNDX)
        x = e.MarginBounds.Left
        h = 0

        ' reset X for data
        x = e.MarginBounds.Left

        ' print the data
        For Each cell As DataGridViewCell In row.Cells
            If cell.Visible Then
                rc = New Rectangle(x, y, cell.Size.Width, cell.Size.Height)

                ' SAMPLE CODE: How To 
                ' up a RowPrePaint rule
                'If Convert.ToDecimal(row.Cells(5).Value) < 9.99 Then
                '    Using br As New SolidBrush(Color.MistyRose)
                '        e.Graphics.FillRectangle(br, rc)
                '    End Using
                'End If

                e.Graphics.DrawRectangle(Pens.Black, rc)

                Select Case dgvZZ.Columns(cell.ColumnIndex).DefaultCellStyle.Alignment
                    Case DataGridViewContentAlignment.BottomRight,
                         DataGridViewContentAlignment.MiddleRight
                        fmt.Alignment = StringAlignment.Far
                        rc.Offset(-1, 0)
                    Case DataGridViewContentAlignment.BottomCenter,
                        DataGridViewContentAlignment.MiddleCenter
                        fmt.Alignment = StringAlignment.Center
                    Case Else
                        fmt.Alignment = StringAlignment.Near
                        rc.Offset(2, 0)
                End Select

                e.Graphics.DrawString(cell.FormattedValue.ToString(),
                                      dgvZZ.Font, Brushes.Black, rc, fmt)

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

        Next
        y += h
        ' next row to print
        mRow = thisNDX + 1

        If y + h > e.MarginBounds.Bottom Then
            e.HasMorePages = True
            ' mRow -= 1   causes last row to rePrint on next page
            newpage = True
            Return
        End If
    Next


End Sub

Note that there is an Id column set to invisible in the DGV, the Color column is centered and Price is left justified - these are all settings picked up from the control. Also note that the text is moved away from the gridlines just a bit.


The last bullet point above, You will also want to reset mRow and newpage either in the button click or BeginPrint event. means this:

Private Sub PrintDocument1_BeginPrint(sender As Object, 
          e As PrintEventArgs) Handles PrintDocument1.BeginPrint
    mRow = 0
    newpage = True
    PrintPreviewDialog1.PrintPreviewControl.StartPage = 0
    PrintPreviewDialog1.PrintPreviewControl.Zoom = 1.0
End Sub

After you preview the mRow variable will indicate that all the rows have been printed. If the user clicks Print or goes back for another Preview, nothing will print. This code also resets the first page to show and the initial Zoom.

这篇关于如何在 vb.net 中打印带有标题的 datagridview 表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆