Results 1 to 6 of 6

Thread: [RESOLVED] PrintPreviewDialog showing last page only

  1. #1

    Thread Starter
    Junior Member
    Join Date
    Apr 2009
    Posts
    31

    Resolved [RESOLVED] PrintPreviewDialog showing last page only

    Hi,
    I am using visual basic net on VS2019 windows 10.
    Scenario.
    Our store has a regular catalogue of specials which can include hundreds of products.
    We have pre-printed pages with blank areas for us to print on. These pages are perforated so they separate into tickets (as many as 8 per page).

    Prior to the PrintPage event
    I have written code which creates a list of pages. (Basically a list of classes showing what to draw)
    I have not included this code below because it works fine.
    I have set the dialog document property to mdoc after setting the mdoc.defaultpagesettings etc

    Problem
    The printpreview only displays the last page.
    The mdoc_printpage event is fired by my calling the printpreviewdialog.showdialog method after creating my list of pages i.e. _Pages()

    Here is my code...

    Code:
    Private Sub mDoc_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles MDoc.PrintPage
            Try
                With e.Graphics
                    .TextRenderingHint = Drawing.Text.TextRenderingHint.AntiAlias
                    'loop pages in the list
                    For i2 = 0 To _Pages.Count - 1
                        'get the elements to draw on this page
                        Dim _Elements As List(Of ClsElement) = _Pages(i2).GetElements
                        'loop elements and draw
                        For i = 0 To _Elements.Count - 1
                            'description
                            Dim Xpos As Integer = _Elements(i).Rect.X + (_Elements(i).Rect.Width / 2)
                            Dim yPos As Integer = _Elements(i).Rect.Top + 3
                            Dim A As New StringFormat
                            A.Alignment = StringAlignment.Center
                            A.LineAlignment = StringAlignment.Near
                            Dim St As Integer = _Elements(i).SetText(e.Graphics)
                            .DrawString(_Elements(i).text, FontMedProp, Brushes.Black, Xpos, yPos, A)
                            'price
                            yPos = _Elements(i).Rect.Top + (_Elements(i).Rect.Height / 2) + 10
                            .DrawString(_Elements(i).price, FontLgeProp, Brushes.Black, Xpos, yPos, A)
                            'barcode
                            yPos = _Elements(i).Rect.Bottom - 20
                            A.Alignment = StringAlignment.Near
                            .DrawString(_Elements(i).barcode, FBarcodeHalf, Brushes.Black, Xpos, yPos, A)
                            A.Alignment = StringAlignment.Far
                            .DrawString(_Elements(i).barcode, FontSmlProp, Brushes.Black, Xpos, yPos, A)
                            .DrawRectangle(Pens.Black, _Elements(i).Rect)
                        Next
                        'start a new page?
                        If i2 = _Pages.Count - 1 Then
                            e.HasMorePages = False
                            Exit Sub
                        Else
                            e.HasMorePages = True
                        End If
                    Next
                End With
    
            Catch ex As Exception
                WriteToErrorFile(ex)
            End Try
        End Sub
    I can't see where I have gone wrong.
    I suspect e.hasmorepages is the culprit but it looks OK to me.

    Any ideas anyone?
    Thanks in advance.

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

    Re: PrintPreviewDialog showing last page only

    It is overwriting your previous pages, if I’m not mistaken. You need to use a variable outside the print page to hold the current page, so instead of…

    Code:
    For i = 0 To _Elements.Count - 1
    You’d use…

    Code:
    For i =  yourExternalVariable To yourExternalVariable
    You’d increment yourExternalVariable by one after the loop, and set e.hasmorepages to true, only if yourExternalVariable < pages.count

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

    Re: PrintPreviewDialog showing last page only

    I’m not at my computer at the moment, but it looks like it’s the i2 loop you need to change as I suggested…

  4. #4
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,350

    Re: PrintPreviewDialog showing last page only

    If you have a list of N items and you want to print M to a page then your code should look something like this:
    vb.net Code:
    1. Private Const ItemsPerPage As Integer = 8
    2.  
    3. Private items As New List(Of String)
    4. Private startIndexForPage As Integer
    5.  
    6. Private Sub PrintDocument1_BeginPrint(sender As Object, e As PrintEventArgs) Handles PrintDocument1.BeginPrint
    7.     startIndexForPage = 0
    8. End Sub
    9.  
    10. Private Sub PrintDocument1_PrintPage(sender As Object, e As Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
    11.     'Print up to the number of items per page or the end of the list, whichever comes first.
    12.     For i = startIndexForPage To Math.Min(items.Count, startIndexForPage + ItemsPerPage) - 1
    13.         'Print item at index i.
    14.     Next
    15.  
    16.     startIndexForPage += ItemsPerPage
    17.  
    18.     'There are more pages to print if and only if the start index is still within the bounds of the list.
    19.     e.HasMorePages = startIndexForPage < items.Count
    20. End Sub

  5. #5
    Super Moderator jmcilhinney's Avatar
    Join Date
    May 2005
    Location
    Sydney, Australia
    Posts
    110,350

    Re: PrintPreviewDialog showing last page only

    In the code you posted, is _Pages a list of objects that are to be printed one to a page? If so then why do you have a loop over that list in your PrintPage event handler? As the name suggests, the PrintPage event handler prints a page. If you have a list of pages to print then you process one item from that list each time the PrintPage event is raised. If _Pages is such a list then you need an index into that list stored OUTSIDE the PrintPage event handler. That index needs to be initialised to zero and incremented in the event handler, e.g.
    vb.net Code:
    1. Private items As New List(Of String)
    2. Private itemIndex As Integer
    3.  
    4. Private Sub PrintDocument1_BeginPrint(sender As Object, e As PrintEventArgs) Handles PrintDocument1.BeginPrint
    5.     itemIndex = 0
    6. End Sub
    7.  
    8. Private Sub PrintDocument1_PrintPage(sender As Object, e As Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
    9.     'Print the item at itemIndex here.
    10.  
    11.     itemIndex += 1
    12.  
    13.     e.HasMorePages = itemIndex < items.Count
    14. End Sub

  6. #6

    Thread Starter
    Junior Member
    Join Date
    Apr 2009
    Posts
    31

    Re: PrintPreviewDialog showing last page only

    Thanks guys.
    You were right jmcilhinney. My mistake was not realising the e.hasmorepages re-triggers the printpage event.
    Once I took that first loop out everything fell into place.
    I will mark this as resolved.
    Thanks again.

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