首页 > 解决方案 > 使用 Foreach 打印多页 (e.HasMorepages)

问题描述

我有一个问题,我希望有人可以帮助我。

我想打印一页,但如果页面比第一页长,我想打印多页。我见过很多使用 e.HasMorePages 的代码示例。

更新

这是我当前的代码,它显示了第二页,但它是空白的。如果有人可以帮助我,那就太好了。

 Private Sub PrintDocument_BO_PrintPage(sender As Object, e As Printing.PrintPageEventArgs) Handles PrintDocument_BO.PrintPage


        Static page As Integer = 1
        Dim startPosition As Integer = (page - 1) * PrintDocument_BO.DefaultPageSettings.Bounds.Height
        Static maxPages As Integer = 0

        If page = 1 Then
            For Each ctrl1 As Control In PrintBackorder.PrintBO_panel.Controls
                If TypeOf ctrl1 Is TextBox Or TypeOf ctrl1 Is Label Or TypeOf ctrl1 Is PictureBox Then
                    ctrl1.Tag = Int((ctrl1.Top + ctrl1.Height) / PrintDocument_BO.DefaultPageSettings.Bounds.Height) + 1
                    If CInt(ctrl1.Tag) > maxPages Then maxPages = CInt(ctrl1.Tag)
                End If
            Next
            For Each ctrl2 As Control In PrintBackorder.BOLayoutPanel.Controls
                If TypeOf ctrl2 Is TextBox Or TypeOf ctrl2 Is Label Or TypeOf ctrl2 Is PictureBox Then
                    ctrl2.Tag = Int((ctrl2.Top + ctrl2.Height) / PrintDocument_BO.DefaultPageSettings.Bounds.Height) + 1
                    If CInt(ctrl2.Tag) > maxPages Then maxPages = CInt(ctrl2.Tag)
                End If
            Next
        End If

        Dim sf = New StringFormat()
        For Each ctrl1 As Control In PrintBackorder.PrintBO_panel.Controls
            If CInt(ctrl1.Tag) = page Then
                If TypeOf ctrl1 Is TextBox Or TypeOf ctrl1 Is Label Then
                    e.Graphics.DrawString(ctrl1.Text, ctrl1.Font, Brushes.Black, ctrl1.Bounds.Location)

                ElseIf TypeOf ctrl1 Is PictureBox Then
                    'e.Graphics.DrawImage(DirectCast(ctrl, PictureBox).Image, New PointF(ctrl.Left, ctrl.Top - startPosition))

                    Dim myBitmap1 = New Bitmap(PrintBackorder.picBarcode.Width, PrintBackorder.picBarcode.Height - 5)
                    'Dim myBitmap1 As Bitmap = New Bitmap(PrintBackorder.picBarcode.Width, PrintBackorder.picBarcode.Height)
                    PrintBackorder.picBarcode.DrawToBitmap(myBitmap1, New Rectangle(0, 0, PrintBackorder.picBarcode.Width, PrintBackorder.picBarcode.Height))
                    e.Graphics.InterpolationMode = Drawing.Drawing2D.InterpolationMode.HighQualityBicubic
                    e.Graphics.PixelOffsetMode = PixelOffsetMode.HighQuality
                    'e.Graphics.SmoothingMode = Drawing.Drawing2D.SmoothingMode.HighQuality
                    e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor
                    e.Graphics.CompositingQuality = Drawing.Drawing2D.CompositingQuality.HighQuality
                    e.Graphics.DrawImage(myBitmap1, 625, 50)

                End If
            End If
        Next
        For Each ctrl2 As Control In PrintBackorder.BOLayoutPanel.Controls 'PrintBackorder.PrintBO_panel.Controls
            If CInt(ctrl2.Tag) = page Then
                If TypeOf ctrl2 Is TextBox Or TypeOf ctrl2 Is Label Then

                    sf.Alignment = If(PrintBackorder.BOLayoutPanel.GetColumn(ctrl2) < 2, StringAlignment.Near, StringAlignment.Far)

                    e.Graphics.DrawString(ctrl2.Text, ctrl2.Font, Brushes.Black, PrintBackorder.PrintBO_panel.PointToClient(PrintBackorder.BOLayoutPanel.PointToScreen(ctrl2.Bounds.Location)), sf)

                End If
            End If
        Next

        page += 1
        If page > maxPages Then
            e.HasMorePages = False
            page = 1
            maxPages = 0
            MsgBox("done")
        Else
            e.HasMorePages = True
        End If
 End Sub

我知道我不应该使用 For Each 循环,但我不知道在这种情况下如何使用 While 循环。

标签: vb.netwinformsforeachprinting

解决方案


以下是评论中提供的原则的一般示例:

'The data to be printed.
Private records As New List(Of String)

'The index of the next record to be printed.
Private recordIndex As Integer

Private Sub Button1_Click(...) Handles Button1.Click
    'Start printing from the first record.
    recordIndex = 0
    PrintDocument1.Print()
End Sub

Private PrintDocument1_PrintPage(...) Handles PrintDocument1.PrintPage
    Dim startRecordIndex = recordIndex

    'Print 10 records or, if there are not 10 records left, to the end of the list.
    Dim endRecordIndex = Math.Min(recordIndex + 9, records.Count - 1)

    For startRecordIndex To endRecordIndex
        Dim record = records(recordIndex)

        e.Graphics.DrawString(record, ...)
    Next

    'The next page will start at the next unprinted record if there is one.
    recordIndex = endRecordIndex + 1
    e.HasMorePages = recordIndex < records.Count
End Sub

推荐阅读