Learn how to a build a cloud-first strategyRegister Now

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 6676
  • Last Modified:

VB.Net 2008 Printing with PrintDocument

Hi Experts,

i need to print some information and I've begun using the printdocument, printdialog and

What i'm trying to print is contact information from my contact manager that i'm working on.

So far I have been able to get the following to print:
document header w/ company name
the billing and shipping addresses with a box around each
the data from my datagridview (date,user,note)

This is the format of page 1:
<header on page with company name>

***************  ****************
* Billing Address  *  * Shipping Address *
*                          *  *                             *
***************  ****************

<date>  <user>  <note>
<date>  <user>  <note>

etc


<footer with page x of y>


This is the format of pages 2+

<header on page with company name>

<date>  <user>  <note>
<date>  <user>  <note>

etc


<footer with page x of y>


what i'm having trouble with is determining when to start another page (e.hasmorepages=true) and getting it to print only the header, data from the datagridview(Contacts_NoteHistory) (date,user,note) and footer on the 2nd page.

The code below works for the header, addresses, and some of the notes, but when it reaches the bottom of the page it starts to squish the text closer together.

The code i'm using to print is below (I know - it's horrible =) )

Global_GetControlByTag is a function I wrote to get a control by its tag based on it's parent.



Private Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
        ' clear the page
        e.Graphics.Clear(Color.White)
        ' set the fonts used
        Dim FontName As String = "Verdana"
        Dim NormalFont As New Font(FontName, 10)
        Dim BoldFont As New Font(FontName, 10, FontStyle.Bold)
 
        ' initializing the font to be used for printing
        Dim PrintAreaHeight, PrintAreaWidth, marginLeft, marginTop As Int32
        With PrintDocument1.DefaultPageSettings
            .Margins.Top = 50
            .Margins.Left = 50
            .Margins.Bottom = 50
            .Margins.Right = 50
            ' initializing local variables to hold margin values that will serve
            ' as the X and Y coordinates for the upper left corner of the printing
            ' area rectangle
            PrintAreaHeight = .PaperSize.Height - .Margins.Top - .Margins.Bottom
            PrintAreaWidth = .PaperSize.Width - .Margins.Left - .Margins.Right
            ' X and Y coordinate
            marginLeft = .Margins.Left
            marginTop = .Margins.Top
        End With
 
        If PrintDocument1.DefaultPageSettings.Landscape Then
            ' if the user selects landscape mode, swap the printing area height and width
            Dim intTemp As Int32
            intTemp = PrintAreaHeight
            PrintAreaHeight = PrintAreaWidth
            PrintAreaWidth = intTemp
        End If
 
        'draw temporary lines at the borders, remove when done
 
        e.Graphics.DrawLine(Pens.Black, marginLeft, marginTop, PrintAreaWidth, marginTop)
        e.Graphics.DrawLine(Pens.Black, PrintAreaWidth, marginTop, PrintAreaWidth, marginTop + PrintAreaHeight)
        e.Graphics.DrawLine(Pens.Black, PrintAreaWidth, marginTop + PrintAreaHeight, marginLeft, marginTop + PrintAreaHeight)
        e.Graphics.DrawLine(Pens.Black, marginLeft, marginTop, marginLeft, marginTop + PrintAreaHeight)
 
        ' draw the doc header
        Dim cur_text As String = Global_GetControlByTag(Contacts_AddressTabs.TabPages(0), "company").text
        Dim cur_sizeF As SizeF = e.Graphics.MeasureString(cur_text, BoldFont, PrintAreaWidth)
        e.Graphics.DrawString(cur_text, BoldFont, Brushes.Black, (PrintDocument1.DefaultPageSettings.PaperSize.Width - cur_sizeF.Width) / 2, marginTop * 1 / 3)
 
        Dim billing_max_len As Integer = 0
        Dim billing_num_lines As Integer = 0
 
        Dim max_len As Integer = 0
        Dim num_lines As Integer = 0
 
        Dim x As Integer = marginLeft
        Dim y As Integer = marginTop
 
        Dim group_spacing As Integer = 10
        Dim pad As Integer = 5
 
        ' draw the misc info
        cur_text = "Category: " & Contacts_ContactCategory.Text
        cur_sizeF = e.Graphics.MeasureString(cur_text, NormalFont, PrintAreaWidth)
        e.Graphics.DrawString(cur_text, NormalFont, Brushes.Black, x, y)
 
        cur_text = "Found Via: " & Contacts_FoundVia.Text
        e.Graphics.DrawString(cur_text, NormalFont, Brushes.Black, x + PrintAreaWidth / 3, y)
 
        cur_text = "Terms: " & Contacts_PaymentTerms.Text
        e.Graphics.DrawString(cur_text, NormalFont, Brushes.Black, x + PrintAreaWidth * 2 / 3, y)
 
        cur_text = "Type: " & Contacts_ContactType.Text
        e.Graphics.DrawString(cur_text, NormalFont, Brushes.Black, x, y + cur_sizeF.Height)
 
        cur_text = "Agent: " & Contacts_ContactAgent.Text
        e.Graphics.DrawString(cur_text, NormalFont, Brushes.Black, x + PrintAreaWidth / 3, y + cur_sizeF.Height)
 
        cur_text = "Discount: " & Contacts_StdDiscount.Text & "%"
        e.Graphics.DrawString(cur_text, NormalFont, Brushes.Black, x + PrintAreaWidth * 2 / 3, y + cur_sizeF.Height)
 
        ' draw a box around the top data
        e.Graphics.DrawRectangle(Pens.Black, x - pad, y - pad, PrintAreaWidth, 2 * cur_sizeF.Height + pad)
 
        y += cur_sizeF.Height * 3
 
        ' A list of tags for the contact fields (billing & shipping addresses)
        Dim tags As ArrayList = New ArrayList
        With tags
            .Add("company")
            .Add("address 1")
            .Add("address 2")
            .Add("city")
            .Add("state")
            .Add("zip")
            .Add("country")
            .Add("phone")
            .Add("ext")
            .Add("fax")
            .Add("cell")
            .Add("web")
            .Add("mail")
        End With
 
        ' draw the billing and shipping area
        For j As Integer = 0 To 1
            ' billing area, j=0 shipping j=1
            For i As Integer = 0 To tags.Count - 1
                If j = 0 And i = 0 Then
                    ' first round of billing
                    x = marginLeft
                ElseIf j = 1 And i = 0 Then
                    ' first round of shipping
                    billing_max_len = max_len
                    billing_num_lines = num_lines
                    num_lines = 0
                    max_len = 0
                    x = marginLeft + billing_max_len + group_spacing
                End If
                'set the current text
                Select Case i
                    Case 0, 1, 2, 9, 10, 11, 12
                        ' company,addr1,addr2,fax,cell,web,mail
                        cur_text = Global_GetControlByTag(Contacts_AddressTabs.TabPages(j), tags.Item(i)).text
                        If cur_text = "" Then
                            GoTo skip
                        End If
                    Case 3, 4, 5, 6
                        ' city, state, zip, country
                        If i = 3 Then
                            cur_text = Global_GetControlByTag(Contacts_AddressTabs.TabPages(j), tags.Item(i)).text & " " & Global_GetControlByTag(Contacts_AddressTabs.TabPages(j), tags.Item(i + 1)).text & ", " & Global_GetControlByTag(Contacts_AddressTabs.TabPages(j), tags.Item(i + 2)).text & " " & Global_GetControlByTag(Contacts_AddressTabs.TabPages(j), tags.Item(i + 3)).text
                        Else
                            ' skip the others as they've already been done.
                            GoTo skip
                        End If
                    Case 7, 8
                        ' phone, ext
                        If i = 7 Then
                            cur_text = Global_GetControlByTag(Contacts_AddressTabs.TabPages(j), tags.Item(i)).text
                            If Global_GetControlByTag(Contacts_AddressTabs.TabPages(j), tags.Item(i + 1)).text <> "" Then
                                cur_text += " x" & Global_GetControlByTag(Contacts_AddressTabs.TabPages(j), tags.Item(i + 1)).text
                            End If
                        Else
                            ' skip the others as they've already been done.
                            GoTo skip
                        End If
                End Select
                ' get the size of it
                cur_sizeF = e.Graphics.MeasureString(cur_text, NormalFont, PrintAreaWidth)
                ' update the size to hold on to the max len (for rectangle calculations)
 
                e.Graphics.DrawString(cur_text, NormalFont, Brushes.Black, x, y + cur_sizeF.Height * num_lines)
                num_lines += 1
skip:
                If cur_sizeF.Width > max_len Then
                    max_len = cur_sizeF.Width
                End If
            Next
        Next
 
        ' draw the caption text and rectangles around the areas
        e.Graphics.DrawString("Billing Address", NormalFont, Brushes.Black, marginLeft, y - cur_sizeF.Height)
        e.Graphics.DrawRectangle(Pens.Black, marginLeft - pad, y, billing_max_len + 2 * pad, cur_sizeF.Height * billing_num_lines + pad)
        e.Graphics.DrawString("Shipping Address", NormalFont, Brushes.Black, marginLeft + billing_max_len + group_spacing, y - cur_sizeF.Height)
        e.Graphics.DrawRectangle(Pens.Black, marginLeft + billing_max_len - 2 * pad + 2 * group_spacing, y, max_len + 2 * pad, cur_sizeF.Height * num_lines + pad)
 
        ' draw the miscellaneous notes
        x = marginLeft
        y += cur_sizeF.Height * num_lines + pad
 
        cur_text = "Miscellanous Notes"
        cur_sizeF = e.Graphics.MeasureString(cur_text, NormalFont, PrintAreaWidth)
        e.Graphics.DrawString(cur_text, NormalFont, Brushes.Black, x, y)
 
        y += cur_sizeF.Height + 5
 
        cur_text = Contacts_MiscNotes.Text
        cur_sizeF = e.Graphics.MeasureString(cur_text, NormalFont, PrintAreaWidth)
        e.Graphics.DrawString(cur_text, NormalFont, Brushes.Black, x, y)
 
        ' draw the box around miscellaneous notes
        e.Graphics.DrawRectangle(Pens.Black, x - pad, y - pad, cur_sizeF.Width + pad, cur_sizeF.Height + pad)
 
        ' draw the notes
        Dim datex As Integer = marginLeft
        Dim namex As Integer = marginLeft + 100
        Dim notex As Integer = namex + 50
 
        y += cur_sizeF.Height + 5
        Dim intLineCount As Int32 = CInt(PrintAreaHeight - y / Font.Height)
 
        Dim fmt As New StringFormat(StringFormatFlags.LineLimit)
        Dim intLinesFilled, intCharsFitted As Int32
        Dim intCurrentChar As Int32
 
        With Contacts_NoteHistory.Rows
            For i As Integer = 0 To .Count - 1
                e.Graphics.DrawString(Format(.Item(i).Cells("NoteDate").Value, "yyyy-MM-dd"), NormalFont, Brushes.Black, datex, y)
                e.Graphics.DrawString(.Item(i).Cells("UserName").Value, NormalFont, Brushes.Black, namex, y)
                cur_sizeF = e.Graphics.MeasureString(Mid(.Item(i).Cells("NoteText").Value, intCurrentChar + 1), NormalFont, New SizeF(PrintAreaWidth - notex - pad, PrintAreaHeight - y), fmt, intCharsFitted, intLinesFilled)
                Dim rectPrintingArea As New RectangleF(notex, y, PrintAreaWidth - notex - pad, PrintAreaHeight - y)
                e.Graphics.DrawString(Mid(.Item(i).Cells("NoteText").Value, intCurrentChar + 1), NormalFont, Brushes.Black, rectPrintingArea, fmt)
            Next
        End With
    End Sub

Open in new window

0
sgaggerj
Asked:
sgaggerj
1 Solution
 
jjardineCommented:
Here are my thoughts.   Maybe you could create a separate method for both the header and footer printing and the page content.   Then on the print page, keep track of the page you are on and call the correct methods.  maybe use a global variable to track the page number.  Here is some psuedo code.

Print_Page Method
PrintHeader()
SELECT CASE on Page number
   Page 1
       PrintPage1COntent()
  Page 2
      PrintPage2Content()
   etc...

Someplace in here, determien if you have another page to print.. If so,
     Set pagenumber++
     e.HasMorePages = true
PrintFooter()
End Print_Page Method
0
 
sgaggerjAuthor Commented:
That's the angle i was going for, but i'm having trouble 1) figuring out when to start the 2nd page and 2) clearing the 2nd page - i tried e.graphics.clear(color.white) but it didn't clear the printdocument for the 2nd page...
0

Featured Post

New feature and membership benefit!

New feature! Upgrade and increase expert visibility of your issues with Priority Questions.

Tackle projects and never again get stuck behind a technical roadblock.
Join Now