title: listview printing
body: <p>I have found some code using google for listview printing. I modified the code base on my needs. I have some problem if the list view more than one pages. It will not stop counting "Generating Previews" of my document. If I press the cancel it was display the data in multiple pages but the same content.</p>
  
  <p>Any suggestion would greatly appreciated.</p>
  
  <p>Thanks in advance</p>
  
  <p>Here is the code</p>
  
  <pre><code>Public Sub pd_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs)
  Dim pd As New PrintDocument
  Dim CurrRow As Integer = 0
  Dim Ratio As Single = 0
  Dim c As ColumnHeader
  Dim g As Graphics = e.Graphics
  Dim l As Integer = 0 'stores current left  
  Dim iCount As Integer
  Dim f As Font = lsvToPrint.Font
  Dim FontBold As New System.Drawing.Font("Microsoft Sans Serif", 10, FontStyle.Bold)
  Dim b As Brush = Brushes.Black
  Dim currentY As Integer = 0
  Dim maxY As Integer = 0
  Dim gap As Integer = 5
  Dim lvsi As ListViewItem.ListViewSubItem
  Dim colLefts(lsvToPrint.Columns.Count) As Integer
  Dim colWidths(lsvToPrint.Columns.Count) As Integer
  Dim idx As Integer = 0
  Dim ii As Integer
  Dim lr As RectangleF
  e.HasMorePages = False
  
  'Page Settings  
  Dim PSize As Integer = lsvToPrint.Items.Count
  Dim PHi As Double
  With pd.DefaultPageSettings
    Dim Ps As PaperSize
    PHi = PSize * 20 + 350
    Ps = New PaperSize("Cust", 800, PHi)
    .Margins.Top = 15
    .Margins.Bottom = 20
    .PaperSize = Ps
  End With
  
  Dim sfc As New StringFormat
  sfc.LineAlignment = StringAlignment.Center
  sfc.Alignment = StringAlignment.Center
  
  'Title  
  Dim headfont As Font
  Dim X1 As Integer
  Dim Y As Integer
  headfont = New Font("Courier New", 16, FontStyle.Bold)
  X1 = pd.DefaultPageSettings.Margins.Left
  Y = pd.DefaultPageSettings.Margins.Top + 5
  With pd.DefaultPageSettings
    e.Graphics.DrawLine(Pens.Black, 0, Y + 70, e.PageBounds.Width, Y + 70)
  End With
  
  'Headings  
  currentY = 100
  For Each c In lsvToPrint.Columns
    maxY = Math.Max(maxY, g.MeasureString(c.Text, f, c.Width).Height)
    colLefts(idx) = l
    colWidths(idx) = c.Width
    lr = New RectangleF(colLefts(idx), currentY, colWidths(idx), maxY) 
    If lr.Width &gt; 0 Then g.DrawString(c.Text, FontBold, b, lr, sfc)
    l += c.Width
    idx += 1
  Next
  currentY += maxY + gap
  g.DrawLine(Pens.Black, 0, currentY, e.PageBounds.Width, currentY)
  currentY += gap
  'Rows  
  iCount = lsvToPrint.Items.Count - 1
  For ii = CurrRow To iCount
    If (currentY + maxY + maxY) &gt; e.PageBounds.Height Then 'jump down another line to see if this line will fit  
      CurrRow = ii - 1
      e.HasMorePages = True
  
      currentY += maxY + gap
  
      Exit For 'does next page  
  
    End If
  
    l = 0
    maxY = 0
    idx = 0
  
    For Each lvsi In lsvToPrint.Items(ii).SubItems
      maxY = Math.Max(maxY, g.MeasureString(lvsi.Text, f, colWidths(idx)).Height)
  
      lr = New RectangleF(colLefts(idx), currentY, colWidths(idx), maxY)
  
      If lsvToPrint.Columns(idx).Text &lt;&gt; "Name" Then
        If lr.Width &gt; 0 Then g.DrawString(lvsi.Text     , f, b, lr, sfc)
      Else
        If lr.Width &gt; 0 Then g.DrawString(lvsi.Text, f, b, lr)
      End If
      idx += 1
    Next
    currentY += maxY + gap
  Next
  End Sub
  </code></pre>