Results 1 to 22 of 22

Thread: Print scrollable panel

  1. #1

    Thread Starter
    Junior Member
    Join Date
    Jul 2019
    Posts
    30

    Print scrollable panel

    hi folks i want to print a scrollable panel probably more than 4 pages. the panel contain labels, text boxes, list views and picture boxes. How best can i be helped

  2. #2
    Super Moderator si_the_geek's Avatar
    Join Date
    Jul 2002
    Location
    Bristol, UK
    Posts
    41,929

    Re: Print scrollable panel

    Welcome to VBForums

    Thread moved from the 'CodeBank VB.Net' forum (which is for you to post working code examples, not questions) to the 'VB.Net' forum

  3. #3
    Hyperactive Member
    Join Date
    Jun 2018
    Posts
    434

    Re: Print scrollable panel

    That depends on what your panel actally is and how the info gets into the panel controls etc.

    You can capture the panel from the screen as is in a bitmap and then divide it and print it on multiple pages based on size.

    However just printing a bitmap image of the panel will not give the best quality. Plus you need to size the image to the printout paper somehow.

    Is the panel always the same size? What size is it in pixels on the screen? What size is the printout in pixels per inch on the paper?

    If you want high quality printouts you should print the text/graphics from the panel on the printout using vector graphics instead of just printing a screen shot of the panel. This will give better quality but is more effort to do.

    Finally if you draw the info on the panel with gdi+ vector graphics then you can just use the same code to print on paper instead of a panel (with scaling).

    So tell us and show us what your panel looks like and what your printout should look like and exaplain what you have done already and what kind of print quality do you need?

  4. #4

    Thread Starter
    Junior Member
    Join Date
    Jul 2019
    Posts
    30

    Re: Print scrollable panel

    I have tried this but this only takes capture the visible controls one the panel. The the hidden ones are not printed
    Code:
    Dim xmax, ymax, w, h As Integer
            For Each ctrl As Control In Panel1.Controls
                w = ctrl.Left + ctrl.Width
                If xmax < w Then xmax = w
                h = ctrl.Top + ctrl.Height
                If ymax < h Then ymax = h
            Next
    
            Using bmp As Bitmap = New Bitmap(xmax + 10, ymax + 10)
                Using g As Graphics = Graphics.FromImage(bmp)
                    For Each ctrl As Control In Panel1.Controls
                        Dim rect As New Rectangle(ctrl.Left, ctrl.Top, ctrl.Width, ctrl.Height)
                        ctrl.DrawToBitmap(bmp, rect)
                    Next
    
                    e.Graphics.DrawImage(bmp, 0, 0, bmp.Width, bmp.Height)
                End Using
            End Using
    Last edited by Saint Neaj; Aug 24th, 2019 at 10:31 AM.

  5. #5
    Hyperactive Member
    Join Date
    Jun 2018
    Posts
    434

    Re: Print scrollable panel

    Quote Originally Posted by Saint Neaj View Post
    I have tried this but this only takes capture the visible controls one the panel. The the hidden ones are not printed
    Code:
    Dim xmax, ymax, w, h As Integer
            For Each ctrl As Control In Panel1.Controls
                w = ctrl.Left + ctrl.Width
                If xmax < w Then xmax = w
                h = ctrl.Top + ctrl.Height
                If ymax < h Then ymax = h
            Next
    
            Using bmp As Bitmap = New Bitmap(xmax + 10, ymax + 10)
                Using g As Graphics = Graphics.FromImage(bmp)
                    For Each ctrl As Control In Panel1.Controls
                        Dim rect As New Rectangle(ctrl.Left, ctrl.Top, ctrl.Width, ctrl.Height)
                        ctrl.DrawToBitmap(bmp, rect)
                    Next
    
                    e.Graphics.DrawImage(bmp, 0, 0, bmp.Width, bmp.Height)
                End Using
            End Using
    You need to count the controls and keep track of the position to print them. In this example see how there is the pagecount and each control is checked to see if off the bottom of the page. If so set the hasmorepages = true flag to have the system call the print sub again for the next page. See where it sets the hasmorepages?

    The example has a panel with 20 labels and that requires 3 pages to print as shown in the preview. A rectangle is also drawn for the margin settings. See how the labels are fit to the margins?

    To make the example put a panel and button on an empty form. Cut and paste the code. Change the form name as requred. The code makes the labels on the panel so you dont have to.

    Name:  a1.png
Views: 1510
Size:  43.4 KB

    Code:
    Imports System.Drawing.Printing
    
    Public Class Form7
        Public PrintPreviewDialog1 As New PrintPreviewDialog
        Public WithEvents PrintDocument1 As PrintDocument = New PrintDocument
        Public LastControlCount, PageCount, PageY As Integer
    
        Private Sub Form7_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            PrintPreviewDialog1.Document = Me.PrintDocument1
            Panel1.BackColor = Color.White
    
            'add labels to panel
            For i As Integer = 0 To 20
                Dim lab As New Label With {.Parent = Panel1,
                    .Location = New Point(20, i * 100),
                    .Size = New Size(200, 24),
                    .Text = "Label " & i.ToString & ": Test printing panel controls."}
            Next
        End Sub
    
        Private Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
            Dim ControlCount As Integer
            'Dim factor As Double = 1
            Dim rect As Rectangle
            Dim MarginHeight As Integer = CInt((PrintDocument1.DefaultPageSettings.PaperSize.Height -
                                        (PrintDocument1.DefaultPageSettings.Margins.Top + PrintDocument1.DefaultPageSettings.Margins.Bottom)))
    
            For Each ctrl As Control In Panel1.Controls
                Using bmp As Bitmap = New Bitmap(ctrl.Width, ctrl.Height)
                    ControlCount += 1
                    If ControlCount >= LastControlCount Then
                        If ctrl.Bottom < MarginHeight * (PageCount + 1) Then
                            ctrl.DrawToBitmap(bmp, ctrl.ClientRectangle)
                            rect = New Rectangle(CInt(e.MarginBounds.Left + (ctrl.Left)),
                                         CInt((e.MarginBounds.Top + (ctrl.Top)) - (MarginHeight * PageCount)),
                                         CInt(ctrl.Width),
                                         CInt(ctrl.Height))
    
                            e.Graphics.DrawImage(bmp, rect)
                        Else
                            LastControlCount = ControlCount
                            If ControlCount > 0 Then
                                e.HasMorePages = True
                                PageCount += 1
                                Exit For
                            End If
                        End If
                    End If
                End Using
            Next
    
            'draw margin bounds
            e.Graphics.DrawRectangle(Pens.Black, e.MarginBounds)
    
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            LastControlCount = 0
            PageCount = 0
    
            PrintPreviewDialog1.ShowDialog()
    
        End Sub
    End Class
    Last edited by tommytwotrain; Aug 24th, 2019 at 05:28 PM. Reason: code moved drawimage inside if

  6. #6

    Thread Starter
    Junior Member
    Join Date
    Jul 2019
    Posts
    30

    Re: Print scrollable panel

    Quote Originally Posted by tommytwotrain View Post
    You need to count the controls and keep track of the position to print them. In this example see how there is the pagecount and each control is checked to see if off the bottom of the page. If so set the hasmorepages = true flag to have the system call the print sub again for the next page. See where it sets the hasmorepages?

    The example has a panel with 20 labels and that requires 3 pages to print as shown in the preview. A rectangle is also drawn for the margin settings. See how the labels are fit to the margins?

    To make the example put a panel and button on an empty form. Cut and paste the code. Change the form name as requred. The code makes the labels on the panel so you dont have to.

    Name:  a1.png
Views: 1510
Size:  43.4 KB

    Code:
    Imports System.Drawing.Printing
    
    Public Class Form7
        Public PrintPreviewDialog1 As New PrintPreviewDialog
        Public WithEvents PrintDocument1 As PrintDocument = New PrintDocument
        Public LastControlCount, PageCount, PageY As Integer
    
        Private Sub Form7_Load(sender As Object, e As EventArgs) Handles MyBase.Load
            PrintPreviewDialog1.Document = Me.PrintDocument1
            Panel1.BackColor = Color.White
    
            'add labels to panel
            For i As Integer = 0 To 20
                Dim lab As New Label With {.Parent = Panel1,
                    .Location = New Point(20, i * 100),
                    .Size = New Size(200, 24),
                    .Text = "Label " & i.ToString & ": Test printing panel controls."}
            Next
        End Sub
    
        Private Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
            Dim ControlCount As Integer
            'Dim factor As Double = 1
            Dim rect As Rectangle
            Dim MarginHeight As Integer = CInt((PrintDocument1.DefaultPageSettings.PaperSize.Height -
                                        (PrintDocument1.DefaultPageSettings.Margins.Top + PrintDocument1.DefaultPageSettings.Margins.Bottom)))
    
            For Each ctrl As Control In Panel1.Controls
                Using bmp As Bitmap = New Bitmap(ctrl.Width, ctrl.Height)
                    ControlCount += 1
                    If ControlCount >= LastControlCount Then
                        If ctrl.Bottom < MarginHeight * (PageCount + 1) Then
                            ctrl.DrawToBitmap(bmp, ctrl.ClientRectangle)
                        Else
                            LastControlCount = ControlCount
                            If ControlCount > 0 Then
                                e.HasMorePages = True
                                PageCount += 1
                                Exit For
                            End If
                        End If
                    End If
    
                    rect = New Rectangle(CInt(e.MarginBounds.Left + (ctrl.Left)),
                                         CInt((e.MarginBounds.Top + (ctrl.Top)) - (MarginHeight * PageCount)),
                                         CInt(ctrl.Width),
                                         CInt(ctrl.Height))
    
                    e.Graphics.DrawImage(bmp, rect)
    
                End Using
            Next
    
            'draw margin bounds
            e.Graphics.DrawRectangle(Pens.Black, e.MarginBounds)
    
        End Sub
    
        Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
            LastControlCount = 0
            PageCount = 0
    
            PrintPreviewDialog1.ShowDialog()
    
        End Sub
    End Class
    Hmm Thanks but your code print all the pages but some of the controls are not in the correct position as i want it

  7. #7

    Thread Starter
    Junior Member
    Join Date
    Jul 2019
    Posts
    30

    Re: Print scrollable panel

    I have tried this. this work well with labels, text boxes and picture boxes. Now my headache is the list view
    Code:
     Static page As Integer = 1
            Dim startPosition As Integer = (page - 1) * PrintDocument1.DefaultPageSettings.Bounds.Height
            Static maxPages As Integer = 0
    
            If page = 1 Then
                For Each ctrl As Control In Me.Panel1.Controls
                    If TypeOf ctrl Is TextBox Or TypeOf ctrl Is Label Or TypeOf ctrl Is PictureBox Then
                        ctrl.Tag = Int((ctrl.Top + ctrl.Height) / PrintDocument1.DefaultPageSettings.Bounds.Height) + 1
                        If CInt(ctrl.Tag) > maxPages Then maxPages = CInt(ctrl.Tag)
                    End If
                Next
            End If
    
            For Each ctrl As Control In Me.Panel1.Controls
                If CInt(ctrl.Tag) = page Then
                    If TypeOf ctrl Is TextBox Or TypeOf ctrl Is Label Then
                        Dim sf As New System.Drawing.StringFormat
                        If TypeOf ctrl Is TextBox Then
                            If DirectCast(ctrl, TextBox).TextAlign = HorizontalAlignment.Right Then
                                sf.Alignment = StringAlignment.Far
                            Else
                                sf.Alignment = StringAlignment.Near
                            End If
                        ElseIf TypeOf ctrl Is Label Then
                            If DirectCast(ctrl, Label).TextAlign = ContentAlignment.TopLeft Then
                                sf.Alignment = StringAlignment.Near
                            ElseIf DirectCast(ctrl, Label).TextAlign = ContentAlignment.TopRight Then
                                sf.Alignment = StringAlignment.Far
                            End If
                        End If
                        sf.FormatFlags = StringFormatFlags.NoClip
                        e.Graphics.DrawString(ctrl.Text, ctrl.Font, New SolidBrush(ctrl.ForeColor), New RectangleF(ctrl.Left, ctrl.Top - startPosition, ctrl.Width + 50, ctrl.Height), sf)
                    ElseIf TypeOf ctrl Is PictureBox Then
                        If Not DirectCast(ctrl, PictureBox).Image Is Nothing Then
                            e.Graphics.DrawImage(DirectCast(ctrl, PictureBox).Image, New PointF(ctrl.Left, ctrl.Top - startPosition))
                        End If
                    End If
                End If
            Next
    
            page += 1
            If page > maxPages Then
                e.HasMorePages = False
                page = 1
                maxPages = 0
            Else
                e.HasMorePages = True
            End If

  8. #8
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,464

    Re: Print scrollable panel

    As I asked you earlier, can you see everything in the listview without scrolling? It makes a huge difference in how to tackle that...

  9. #9

    Thread Starter
    Junior Member
    Join Date
    Jul 2019
    Posts
    30

    Re: Print scrollable panel

    Quote Originally Posted by .paul. View Post
    As I asked you earlier, can you see everything in the listview without scrolling? It makes a huge difference in how to tackle that...
    No please, the listview are many some visible other are hidden

  10. #10
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,464

    Re: Print scrollable panel

    That's a much more difficult question. What is the View of your ListViews? Is it Details? Whatever it is, it'll need a fairly complex print algorithm. ListViews with contents extending beyond the viewable bounds are a more difficult print job, as in themselves they may extend beyond one printed page...

  11. #11
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,464

    Re: Print scrollable panel

    Here's an example that may help...

    https://code.msdn.microsoft.com/List...inter-7a9be0a7

  12. #12

    Thread Starter
    Junior Member
    Join Date
    Jul 2019
    Posts
    30

    Re: Print scrollable panel

    https://drive.google.com/file/d/1u61...ew?usp=sharing
    short demo of how the list views look like

  13. #13
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,464

    Re: Print scrollable panel

    So you don't have to scroll your listview to see all of the contents?

  14. #14

    Thread Starter
    Junior Member
    Join Date
    Jul 2019
    Posts
    30

    Re: Print scrollable panel

    Quote Originally Posted by .paul. View Post
    So you don't have to scroll your listview to see all of the contents?
    Yes Please, when printed each listview will on the middle of every page(A4 or letter)

  15. #15
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,464

    Re: Print scrollable panel

    As long as your contents are all visible within the unscrolled listview (not the form), you can capture an image of the control and print it like a picturebox image

  16. #16

    Thread Starter
    Junior Member
    Join Date
    Jul 2019
    Posts
    30

    Re: Print scrollable panel

    Quote Originally Posted by .paul. View Post
    As long as your contents are all visible within the unscrolled listview (not the form), you can capture an image of the control and print it like a picturebox image
    Thanks so much but am newbie how could i do this please

  17. #17
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,464

    Re: Print scrollable panel

    Try this...

    Code:
    ElseIf TypeOf ctrl Is ListView Then
                Dim lv As ListView = DirectCast(ctrl, ListView)
                Dim img As New Bitmap(lv.Width, lv.Height)
                lv.DrawToBitmap(img, New Rectangle(Point.Empty, img.Size))
                e.Graphics.DrawImage(img, New PointF(ctrl.Left, ctrl.Top - StartPosition))

  18. #18

    Thread Starter
    Junior Member
    Join Date
    Jul 2019
    Posts
    30

    Re: Print scrollable panel

    Quote Originally Posted by .paul. View Post
    Try this...

    Code:
    ElseIf TypeOf ctrl Is ListView Then
                Dim lv As ListView = DirectCast(ctrl, ListView)
                Dim img As New Bitmap(lv.Width, lv.Height)
                lv.DrawToBitmap(img, New Rectangle(Point.Empty, img.Size))
                e.Graphics.DrawImage(img, New PointF(ctrl.Left, ctrl.Top - StartPosition))
    Thanks so much of your help. Everything worked well as i expected. Many thanks Paul

  19. #19
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,464

    Re: Print scrollable panel

    Ok. Please note we could've solved this sooner, if you'd been more able to explain exactly what you were trying to print...

  20. #20

    Thread Starter
    Junior Member
    Join Date
    Jul 2019
    Posts
    30

    Re: Print scrollable panel

    Quote Originally Posted by .paul. View Post
    Ok. Please note we could've solved this sooner, if you'd been more able to explain exactly what you were trying to print...
    Alright boss, Next time i will be clear. Thanks

  21. #21
    Hyperactive Member
    Join Date
    Jun 2018
    Posts
    434

    Re: Print scrollable panel

    Quote Originally Posted by Saint Neaj View Post
    Thanks so much of your help. Everything worked well as i expected. Many thanks Paul
    Looks like the example in post #5 that was no good in post #6 but is now works "as expected" in post #18?

  22. #22
    eXtreme Programmer .paul.'s Avatar
    Join Date
    May 2007
    Location
    Chelmsford UK
    Posts
    25,464

    Re: Print scrollable panel

    Quote Originally Posted by tommytwotrain View Post
    Looks like the example in post #5 that was no good in post #6 but is now works "as expected" in post #18?
    I think the issue was just text and image locations on the printed page

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width