windows forms printing problem. Won't print second page.

bh0526

Member
Joined
May 11, 2015
Messages
15
Programming Experience
10+
I'm really a C# web developer who suddenly was assigned a VB.Net Windows forms project. The last time i did VB was the 1990's. I'm struggling with printing using the printdocument control. It works fine if my data fits on one page. But now I have a list of orders that needs to print on 2 pages. I cannot get this to work. Presently, I get 3 pages of print but it's the exact same data on each page. I don't know how to use the e.HasMorePages property. It seems like I need to add the hasMorePages = true in the loop where I have the comment 'Print Orders. But I could not get it to work. I counted and it seems I can get 39 order lines on my report. This is in addition to the my header stuff. But after the 39th order prints, I want to skip to a new page, print headings again, and then continue with the 40th order and so on. Can anyone help me figure this out? Here is my code:
VB.NET:
[/FONT][/COLOR][COLOR=#454545][FONT=Segoe UI]Public Sub OrderReport()[/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]        Dim oOrder As New Order(connStringNW)[/FONT][/COLOR]

[COLOR=#454545][FONT=Segoe UI]        ' Loop thru all rows[/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]        ds = SqlHelper.ExecuteDataset(connStringHG, "GetOrdersByOrderDates", DateTimePicker1.Value.ToShortDateString() + " 00:00:00.000",[/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]                                                                             DateTimePicker2.Value.ToShortDateString() + " 23:59:59.999")[/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]        For Each row As DataRow In ds.Tables(0).Rows[/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]            lId.Add(CStr(row("Id")))[/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]            lName.Add(CStr(row("CustomerName")))[/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]            lTot.Add(CStr(row("OrderTotal")))[/FONT][/COLOR]

[COLOR=#454545][FONT=Segoe UI]            ' Select the printer[/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]            Dim sDefaultPrinter As String = GetDefaultPrinterName()[/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]            PrintDocument4.PrinterSettings.PrinterName = cboPrinter.Text[/FONT][/COLOR]

[COLOR=#454545][FONT=Segoe UI]            ' PrintDocument4.PrinterSettings.[/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]            PrintDialog4.Document = PrintDocument4[/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]            PrintDocument4.PrinterSettings.Copies = 1[/FONT][/COLOR]

[COLOR=#454545][FONT=Segoe UI]        Next[/FONT][/COLOR]

[COLOR=#454545][FONT=Segoe UI]        PrintDocument4.Print()[/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]        btnExit.Visible = True[/FONT][/COLOR]

[COLOR=#454545][FONT=Segoe UI]    End Sub[/FONT][/COLOR]






[COLOR=#454545][FONT=Segoe UI]Private Sub PrintDocument4_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument4.PrintPage[/FONT][/COLOR]

[COLOR=#454545][FONT=Segoe UI]        Static loopIndex As Integer = 0[/FONT][/COLOR]

[COLOR=#454545][FONT=Segoe UI]        '------------------------------------------------------[/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]        ' Set Fonts[/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]        '------------------------------------------------------[/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]        printFont18B = New Font("Tahoma", 18, FontStyle.Bold)[/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]        printFont11B = New Font("Tahoma", 11, FontStyle.Bold)[/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]        printFont18 = New Font("Tahoma", 18)[/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]        printFont11 = New Font("Tahoma", 11)[/FONT][/COLOR]

[COLOR=#454545][FONT=Segoe UI]        iLine = 100

[/FONT][/COLOR]      iPageNum += 1        If iPageNum <= iTotalPages Then
            e.HasMorePages = True
        Else
            e.HasMorePages = False
            iPageNum = 0
        End If

[COLOR=#454545][FONT=Segoe UI]        '------------------------------------------------------[/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]        ' Print Header Info[/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]        '------------------------------------------------------[/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]        e.Graphics.DrawString("Modern Robotics Inc.", printFont11B, Brushes.Black, 20, 30)[/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]        e.Graphics.DrawString("Orders", printFont18B, Brushes.Black, 340, 20)[/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]        e.Graphics.DrawString("Date: ", printFont11B, Brushes.Black, 660, 30)[/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]        e.Graphics.DrawString(Today(), printFont11B, Brushes.Black, 710, 30)[/FONT][/COLOR]

[COLOR=#454545][FONT=Segoe UI]        e.Graphics.DrawString("From Start Date: ", printFont11B, Brushes.Black, 260, 65)[/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]        e.Graphics.DrawString(DateTimePicker1.Value.ToShortDateString(), printFont11B, Brushes.Black, 400, 65)[/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]        e.Graphics.DrawString("To: ", printFont11B, Brushes.Black, 495, 65)[/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]        e.Graphics.DrawString(DateTimePicker2.Value.ToShortDateString(), printFont11B, Brushes.Black, 530, 65)[/FONT][/COLOR]

[COLOR=#454545][FONT=Segoe UI]        e.Graphics.DrawString("Order Id", printFont11B, Brushes.Black, 100, 110)[/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]        e.Graphics.DrawString("Customer", printFont11B, Brushes.Black, 180, 110)[/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]        e.Graphics.DrawString("Order Total", printFont11B, Brushes.Black, 555, 110)[/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]        iLine = 140[/FONT][/COLOR]

[COLOR=#454545][FONT=Segoe UI]        ' Print Orders[/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]        Dim j As Integer[/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]        For j = 0 To lId.Count - 1[/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]            e.Graphics.DrawString(lId(j).ToString(), printFont11, Brushes.Black, 100, iLine)[/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]            e.Graphics.DrawString(lName(j).ToString(), printFont11, Brushes.Black, 180, iLine)[/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]            e.Graphics.DrawString(Format(Convert.ToSingle(lTot(j)), "0.00"), printFont11, Brushes.Black, 555, iLine)[/FONT][/COLOR]

[COLOR=#454545][FONT=Segoe UI]            iLine += 25[/FONT][/COLOR][COLOR=#454545][FONT=Segoe UI]        [/FONT][/COLOR]
[COLOR=#454545][FONT=Segoe UI]        Next j[/FONT][/COLOR]

[COLOR=#454545][FONT=Segoe UI]        iLine = 0[/FONT][/COLOR]

[COLOR=#454545][FONT=Segoe UI]    End Sub
[/FONT][/COLOR][COLOR=#454545][FONT=Segoe UI]
 
Yeah, the IT director at my client is a dinosaur. They are forever stuck in the VB6 world. If you look at my Imports, I have a reference named OrderClasses which contains all my classes with properties, methods, constructors, etc for the order entry system. When the guy saw that, he demanded that I remove it since his staff would be confused. So I do use the Microsoft Application Data Blocks which simply encapsulates the ADO.Net code and allows data access to the SQL db with one line of code. But I hope he does not see that since he would probably make me get rid of that as well. Luckily, he does not put any restrictions on me when I built their web site. I use MVC 5 for that. I would not even work with this client if he restricted my web development.

I'll try your suggestions.
 
Why would his staff even be in the source code, are they programmers? If not I would honestly just tell him he's out of his league, politely. You should be able to do your job without artificial and nonsensical restrictions. Not using SSRS or avoiding external libraries you don't have the source to is a reasonable restriction, but telling you how to factor your own code is rude and none of his business, especially considering the state of the existing code...
 
He has a staff of programmers. But they have never gotten into .Net. I use my class library, OrderClasses, for their web site. So I spent a lot of time creating this. It's their code, not mine as I developed it for them. They own the source code. I told him it's not a difficult concept to teach his staff but he said they don't have time. I've billed this client several hundred $$$ over the last 2 years so I just do what I'm told. Problem is, I suck at windows development. I'm almost done with this client and will get back to web development soon.
 
I was able to get this working. If anyone is interested, here is my code:

' Print Orders
Dim j As Integer
Dim row As Integer = e.MarginBounds.Top

For i As Integer = index To lId.Count - 1
e.Graphics.DrawString(lId(i).ToString(), printFont11, Brushes.Black, 100, iLine)
e.Graphics.DrawString(lName(i).ToString(), printFont11, Brushes.Black, 180, iLine)
e.Graphics.DrawString(Format(Convert.ToSingle(lTot(i)), "0.00"), printFont11, Brushes.Black, 555, iLine)

iLine += 25

index = i
row += 20
If row > e.MarginBounds.Bottom - 120 Then
e.HasMorePages = True
Exit Sub
Else
'continue printing
End If

Next

I'm not a big fan of this type of printing. SSRS is much more powerful / easier and comes with SQL. All my customers use SQL database and they all embraced SSRS. But this one particular client will not use it since they live in the past.
 
More powerful? I'm afraid that you simply don't know what you're talking about. Using a PrintDocument you can print anything that you can draw using GDI+. The fact is that you simply don't know how to use it properly. That's fine but, while using SSRS may be easier for things that SSRS can display, to say that it's more powerful is simply ignorant.
 
Back
Top