printpreviewdialog HasMorePages ?

showai

Member
Joined
Apr 27, 2009
Messages
7
Programming Experience
Beginner
Hi,
i have a print preview button where when user clicks, the preview doc will appear. everything else is working fine, just that it cant seem to be able to continue on a next page when the records exceed the 1st page.

i've tried the following code but it just keeps generating the previews, until i press cancel. And the generated previews are the same as the first page.

VB.NET:
  If ypos > e.MarginBounds.Bottom Then
                        If dr5.HasRows Then
                            intpagenumber += 1
                            e.HasMorePages = True
                        Else
                            e.HasMorePages = False
                        End If
                        Exit Sub
                    End If

are there any other ways of making it work?
thanks in advance.
 
You need to loop through the rows using a pointer, and then use the pointer value to decide whether you have finished rather than "dr5.HasRows" (which will always be true unless you are removing the rows).

Post the whole PrintPage and BeginPrint event code if it still wont work.
 
Thanks for replying! I understand what you're saying about the pointer, but i don't know what to use for the pointer.

is this the code you want?

VB.NET:
    Private Sub Print_PrintPage(ByVal sender As Object, ByVal e As _
System.Drawing.Printing.PrintPageEventArgs)

        Try

            Dim conn As New SqlConnection _
                 ("data source=VT001\SQLEXPRESS; integrated security=true _
initial catalog=CRM; MultipleActiveResultSets=True")

            conn.Open()


Dim appFont As New Font("Arial", 10, FontStyle.Regular Or FontStyle.Regular)

            Dim countMC1 As Integer = 0
            Dim countMC2 As Integer = 0


Dim cmdCountMC As New SqlCommand("SELECT COUNT(*) from Contact", conn)

            cmdCountMC.ExecuteScalar()
            Dim datareader2 = cmdCountMC.ExecuteScalar()
            countMC1 = datareader2


       Dim command2 As New SqlCommand("select * from Contact", conn)

                Dim dr5 As SqlDataReader
                dr5 = command2.ExecuteReader()
                If dr5.HasRows Then

                    Dim mc As String = "Contact: "
               g.DrawString(mc, appFont, New SolidBrush(Color.Black), 10, 130)

                    Dim m1 As String = "Group Name "
               g.DrawString(m1, appFont, New SolidBrush(Color.Black), 10, 160)

                    Dim m2 As String = "First Name "
               g.DrawString(m2, appFont, New SolidBrush(Color.Black), 150, 160)

                    Dim m3 As String = "Last Name"
               g.DrawString(m3, appFont, New SolidBrush(Color.Black), 320, 160)

                    Dim m4 As String = "Handphone Number"
               g.DrawString(m4, appFont, New SolidBrush(Color.Black), 470, 160)

                    Dim m5 As String = "Date"
               g.DrawString(m5, appFont, New SolidBrush(Color.Black), 650, 160)

                    Dim m6 As String = "Note"
               g.DrawString(m6, appFont, New SolidBrush(Color.Black), 700, 160)

                    g.DrawLine(bPen, 0, 180, 1000, 180)

                    Dim mc1 As String = Nothing
                    Dim mc2 As String = Nothing
                    Dim mc3 As String = Nothing
                    Dim mc4 As String = Nothing
                    Dim mc5 As String = Nothing
                    Dim mc6 As String = Nothing


                    While dr5.Read

                        mc1 += dr5("grpName") + vbCrLf
                        mc2 += dr5("firstName") + vbCrLf
                        mc3 += dr5("lastName") + vbCrLf
                        mc4 += dr5("hpNo") + vbCrLf
                        mc5 += dr5("date") + vbCrLf
                        mc6 += dr5("notes") + vbCrLf

                    End While


                    Dim m9 As String = Nothing
                    m9 = mc1
              g.DrawString(m9, appFont, New SolidBrush(Color.Black), 10, 200)
                    Dim m10 As String = Nothing
                    m10 = mc2
              g.DrawString(m10, appFont, New SolidBrush(Color.Black), 150, 200)
                    Dim m11 As String = Nothing
                    m11 = mc3
              g.DrawString(m11, appFont, New SolidBrush(Color.Black), 320, 200)
                    Dim m12 As String = Nothing
                    m12 = mc4
              g.DrawString(m12, appFont, New SolidBrush(Color.Black), 470, 200)
                    Dim m13 As String = Nothing
                    m13 = mc5
              g.DrawString(m13, appFont, New SolidBrush(Color.Black), 650, 200)
                    Dim m14 As String = Nothing
                    m14 = mc6
              g.DrawString(m14, appFont, New SolidBrush(Color.Black), 700, 200)

                    dr5.Close()

                    countMC2 = (countMC1 * 16) + 20 + 200

                    g.DrawLine(bPen, 0, countMC2, 1000, countMC2)

                End If


            Dim ypos As Integer = countMC2

            Dim intpagenumber As Integer

            If ypos > e.MarginBounds.Bottom Then

                If dr5.HasRows Then

                intpagenumber += 1

                e.HasMorePages = True

            Else

                e.HasMorePages = False

                End If

                Exit Sub

            End If

            conn.Close()

        Catch ex As Exception
            MsgBox(ex.Message)
        End Try

    End Sub
sorry, it's a little messy.

Thanks in advance.
 
sorry, it's a little messy

:eek:

Joking aside, I think you should *relatively* go back and modify the whole code. PrintPage should (in my view) only be used to cycle through already loaded data. You need to pre-load all your data before you get to the PrintPage event - you can either do this in the BeginPrint event, or even earlier than that.

To understand about pointers and how to use them within the PrintPage event, look at this post I know it doesnt specifically relate to data, but it should give you direction.

As some side notes (in no particular order):-

1. Where did 'g' come from - normally people use e.graphics within the PrintPage event, but I cant see where you are declaring g?

2. Define your fonts and brushes outside the routine, and then you dont end up with multiple copies of them. For example:-

VB.NET:
Private appFont As New Font("Arial", 10, FontStyle.Regular Or FontStyle.Regular)
Private brBlack as New SolidBrush (Color.Black)

3. You should turn Option Strict On. It will give you some errors, but as your programming knowledge increases, it will help - trust me ;)

4. Do you intend to print to paper in the end? If so, and you work in metric, make your life easier and scale the page before you start (so you can check it with a tape measure :D) :-

VB.NET:
e.Graphics.PageUnit = GraphicsUnit.Millimeter
 
Hi, sorry for the super late reply.

I was trying to get it working plus doing other parts for my project. I'm finally able to get the correct number of pages out! Thanks for the example! :D

but it's still printing with the same results. any idea how to solve?

Thanks again! :D
 
Thanks for the reply :)

VB.NET:
    Dim mailName As String
    Dim linePerPage As Integer
    Dim pageNumber As Integer
    Dim pageToPrint As Integer
    Dim lineToPrint As Integer
    Dim countRec As Integer
    Dim n As Integer


    Public Sub readDb()
        Try

            Dim conn As New SqlConnection _
                    ("data source=VT001\SQLEXPRESS; integrated security=true; initial catalog=CRM; MultipleActiveResultSets=True")
            conn.Open()

            Dim cmdC As New SqlCommand("SELECT COUNT(*) from contact", conn)
            cmdC.ExecuteScalar()
            countRec = CInt(cmdC.ExecuteScalar())
   

            Dim cmd As New SqlCommand("select mailName from Contact", conn)

            Dim dr As SqlDataReader
            dr = cmd.ExecuteReader()

            If dr.HasRows Then

                While dr.Read()
                    mailName += CStr(dr("mailName")) + vbCrLf
                End While
                dr.Close()

            End If

            conn.Close()

        Catch ex As Exception
            MsgBox(ex.Message)
        End Try

    End Sub

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

            Call readDb()

            Dim bottom As Integer = e.MarginBounds.Bottom
            Dim g As Graphics = e.Graphics
            Dim font As New Font("Arial", 10, FontStyle.Regular Or FontStyle.Regular)
            Dim brush As New SolidBrush(Color.Black)
            Dim y As Single = e.PageBounds.Top
            Dim x As Single = e.MarginBounds.Left

            Dim maxLine As Integer = CInt(bottom / 16)

            pageNumber += 1

            For a As Integer = 1 To maxLine

                g.DrawString(mailName, font, brush, x + 5, y + 16)
                y += 16

            Next


            linePerPage = CInt(e.MarginBounds.Bottom / 16)

            pageToPrint = CInt(Math.Ceiling(Convert.ToDouble(countRec / linePerPage)))


            If pageNumber < pageToPrint Then
                e.HasMorePages = True
            Else
                e.HasMorePages = False
                Exit Sub
            End If



        Catch ex As Exception
            MsgBox(ex.Message)
        End Try

i think the for-loop is wrong. I did it with numbers (from your example) and it's working fine.
 
but it's still printing with the same results. any idea how to solve?

It's doing it because you call your readdb function every time you start a new page.

Basically, you should only ever write print functions into the PrintPage event. Everything else (eg retrieving data) should go in the BeginPrint event, which is only ever called once BEFORE any printing starts.
 
I threw everything into BeginPrint. lol :p

I just tried displaying dr("mailName") in a msgbox, and it shows all the records from database as a string. I'm thinking it might be because of this that it keeps printing that string. Is it possible to separate them (like 1row = 1string) ? :confused:
 
I've placed them in an arrayList.

VB.NET:
      maxLine = CInt(e.MarginBounds.Bottom / 16)

            For a As Integer = 1 To maxLine

                For Each str As String In arrayMN

                    countMN += 1
                        g.DrawString(str, font, brush, x + 5, y + 16)
                        y += 16

                Next
            Next

problem now is that it's not going thru the 1st for-loop, and thus not printing in 2nd page (it just got cut off at the bottom of 1st page). Any ways to solve that? :confused:
 
Back
Top