Problems printing DataGridView - vb.net

Hi I am using the following code to print a datagridview. It works but it prints every single column, even the ones that are not visible on the form. Is there a way to make it so it only prints visible columns. Thanks.
Private Structure pageDetails
Dim columns As Integer
Dim rows As Integer
Dim startCol As Integer
Dim startRow As Integer
End Structure
Private pages As Dictionary(Of Integer, pageDetails)
Dim maxPagesWide As Integer
Dim maxPagesTall As Integer
Private Sub PrintDocument1_BeginPrint(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintEventArgs) Handles PrintDocument1.BeginPrint
''this removes the printed page margins
PrintDocument1.OriginAtMargins = True
PrintDocument1.DefaultPageSettings.Margins = New Drawing.Printing.Margins(0, 0, 0, 0)
pages = New Dictionary(Of Integer, pageDetails)
Dim maxWidth As Integer = CInt(PrintDocument1.DefaultPageSettings.PrintableArea.Width) - 40
Dim maxHeight As Integer = CInt(PrintDocument1.DefaultPageSettings.PrintableArea.Height) - 40 + Label1.Height
Dim pageCounter As Integer = 0
pages.Add(pageCounter, New pageDetails)
Dim columnCounter As Integer = 0
Dim columnSum As Integer = DataGridView1.RowHeadersWidth
For c As Integer = 0 To DataGridView1.Columns.Count - 1
If columnSum + DataGridView1.Columns(c).Width < maxWidth Then
columnSum += DataGridView1.Columns(c).Width
columnCounter += 1
Else
pages(pageCounter) = New pageDetails With {.columns = columnCounter, .rows = 0, .startCol = pages(pageCounter).startCol}
columnSum = DataGridView1.RowHeadersWidth + DataGridView1.Columns(c).Width
columnCounter = 1
pageCounter += 1
pages.Add(pageCounter, New pageDetails With {.startCol = c})
End If
If c = DataGridView1.Columns.Count - 1 Then
If pages(pageCounter).columns = 0 Then
pages(pageCounter) = New pageDetails With {.columns = columnCounter, .rows = 0, .startCol = pages(pageCounter).startCol}
End If
End If
Next
maxPagesWide = pages.Keys.Max + 1
pageCounter = 0
Dim rowCounter As Integer = 0
Dim rowSum As Integer = DataGridView1.ColumnHeadersHeight
For r As Integer = 0 To DataGridView1.Rows.Count - 2
If rowSum + DataGridView1.Rows(r).Height < maxHeight Then
rowSum += DataGridView1.Rows(r).Height
rowCounter += 1
Else
pages(pageCounter) = New pageDetails With {.columns = pages(pageCounter).columns, .rows = rowCounter, .startCol = pages(pageCounter).startCol, .startRow = pages(pageCounter).startRow}
For x As Integer = 1 To maxPagesWide - 1
pages(pageCounter + x) = New pageDetails With {.columns = pages(pageCounter + x).columns, .rows = rowCounter, .startCol = pages(pageCounter + x).startCol, .startRow = pages(pageCounter).startRow}
Next
pageCounter += maxPagesWide
For x As Integer = 0 To maxPagesWide - 1
pages.Add(pageCounter + x, New pageDetails With {.columns = pages(x).columns, .rows = 0, .startCol = pages(x).startCol, .startRow = r})
Next
rowSum = DataGridView1.ColumnHeadersHeight + DataGridView1.Rows(r).Height
rowCounter = 1
End If
If r = DataGridView1.Rows.Count - 2 Then
For x As Integer = 0 To maxPagesWide - 1
If pages(pageCounter + x).rows = 0 Then
pages(pageCounter + x) = New pageDetails With {.columns = pages(pageCounter + x).columns, .rows = rowCounter, .startCol = pages(pageCounter + x).startCol, .startRow = pages(pageCounter + x).startRow}
End If
Next
End If
Next
maxPagesTall = pages.Count \ maxPagesWide
End Sub
Private Sub PrintDocument1_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
Dim rect As New Rectangle(20, 20, CInt(PrintDocument1.DefaultPageSettings.PrintableArea.Width), Label1.Height)
Dim sf As New StringFormat
sf.Alignment = StringAlignment.Center
sf.LineAlignment = StringAlignment.Center
e.Graphics.DrawString(Label1.Text, Label1.Font, Brushes.Black, rect, sf)
sf.Alignment = StringAlignment.Near
Dim startX As Integer = 50
Dim startY As Integer = rect.Bottom
Static startPage As Integer = 0
For p As Integer = startPage To pages.Count - 1
Dim cell As New Rectangle(startX, startY, DataGridView1.RowHeadersWidth, DataGridView1.ColumnHeadersHeight)
e.Graphics.FillRectangle(New SolidBrush(SystemColors.ControlLight), cell)
e.Graphics.DrawRectangle(Pens.Black, cell)
startY += DataGridView1.ColumnHeadersHeight
For r As Integer = pages(p).startRow To pages(p).startRow + pages(p).rows - 1
cell = New Rectangle(startX, startY, DataGridView1.RowHeadersWidth, DataGridView1.Rows(r).Height)
e.Graphics.FillRectangle(New SolidBrush(SystemColors.ControlLight), cell)
e.Graphics.DrawRectangle(Pens.Black, cell)
e.Graphics.DrawString(DataGridView1.Rows(r).HeaderCell.Value, DataGridView1.Font, Brushes.Black, cell, sf)
startY += DataGridView1.Rows(r).Height
Next
startX += cell.Width
startY = rect.Bottom
For c As Integer = pages(p).startCol To pages(p).startCol + pages(p).columns - 1
cell = New Rectangle(startX, startY, DataGridView1.Columns(c).Width, DataGridView1.ColumnHeadersHeight)
e.Graphics.FillRectangle(New SolidBrush(SystemColors.ControlLight), cell)
e.Graphics.DrawRectangle(Pens.Black, cell)
e.Graphics.DrawString(DataGridView1.Columns(c).HeaderCell.Value, DataGridView1.Font, Brushes.Black, cell, sf)
startX += DataGridView1.Columns(c).Width
Next
startY = rect.Bottom + DataGridView1.ColumnHeadersHeight
For r As Integer = pages(p).startRow To pages(p).startRow + pages(p).rows - 1
startX = 50 + DataGridView1.RowHeadersWidth
For c As Integer = pages(p).startCol To pages(p).startCol + pages(p).columns - 1
cell = New Rectangle(startX, startY, DataGridView1.Columns(c).Width, DataGridView1.Rows(r).Height)
e.Graphics.DrawRectangle(Pens.Black, cell)
e.Graphics.DrawString(DataGridView1(c, r).Value, DataGridView1.Font, Brushes.Black, cell, sf)
startX += DataGridView1.Columns(c).Width
Next
startY += DataGridView1.Rows(r).Height
Next
If p <> pages.Count - 1 Then
startPage = p + 1
e.HasMorePages = True
Return
Else
startPage = 0
End If
Next
End Sub
Private Sub PrintAMToolStripMenuItem_Click(sender As Object, e As EventArgs) Handles PrintAMToolStripMenuItem.Click
PrintDocument1.DefaultPageSettings.Landscape = True
PrintDocument1.Print()
End Sub

I added If condition to your PrintDocument1_PrintPage and your PrintDocument1_BeginPrint events to check if the column is visible each time there is a loop against your columns:
Private Sub PrintDocument1_BeginPrint(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintEventArgs) Handles PrintDocument1.BeginPrint
''this removes the printed page margins
PrintDocument1.OriginAtMargins = True
PrintDocument1.DefaultPageSettings.Margins = New Drawing.Printing.Margins(0, 0, 0, 0)
pages = New Dictionary(Of Integer, pageDetails)
Dim maxWidth As Integer = CInt(PrintDocument1.DefaultPageSettings.PrintableArea.Width) - 40
Dim maxHeight As Integer = CInt(PrintDocument1.DefaultPageSettings.PrintableArea.Height) - 40 + Label1.Height
Dim pageCounter As Integer = 0
pages.Add(pageCounter, New pageDetails)
Dim columnCounter As Integer = 0
Dim columnSum As Integer = DataGridView1.RowHeadersWidth
For c As Integer = 0 To DataGridView1.Columns.Count - 1
If columnSum + DataGridView1.Columns(c).Width < maxWidth Then
columnSum += DataGridView1.Columns(c).Width
columnCounter += 1
Else
If DataGridView1.Columns(c).Visible = True Then
pages(pageCounter) = New pageDetails With {.columns = columnCounter, .rows = 0, .startCol = pages(pageCounter).startCol}
columnSum = DataGridView1.RowHeadersWidth + DataGridView1.Columns(c).Width
columnCounter = 1
pageCounter += 1
pages.Add(pageCounter, New pageDetails With {.startCol = c})
End If
End If
If c = DataGridView1.Columns.Count - 1 Then
If pages(pageCounter).columns = 0 Then
pages(pageCounter) = New pageDetails With {.columns = columnCounter, .rows = 0, .startCol = pages(pageCounter).startCol}
End If
End If
Next
maxPagesWide = pages.Keys.Max + 1
pageCounter = 0
Dim rowCounter As Integer = 0
Dim rowSum As Integer = DataGridView1.ColumnHeadersHeight
For r As Integer = 0 To DataGridView1.Rows.Count - 2
If rowSum + DataGridView1.Rows(r).Height < maxHeight Then
rowSum += DataGridView1.Rows(r).Height
rowCounter += 1
Else
pages(pageCounter) = New pageDetails With {.columns = pages(pageCounter).columns, .rows = rowCounter, .startCol = pages(pageCounter).startCol, .startRow = pages(pageCounter).startRow}
For x As Integer = 1 To maxPagesWide - 1
pages(pageCounter + x) = New pageDetails With {.columns = pages(pageCounter + x).columns, .rows = rowCounter, .startCol = pages(pageCounter + x).startCol, .startRow = pages(pageCounter).startRow}
Next
pageCounter += maxPagesWide
For x As Integer = 0 To maxPagesWide - 1
pages.Add(pageCounter + x, New pageDetails With {.columns = pages(x).columns, .rows = 0, .startCol = pages(x).startCol, .startRow = r})
Next
rowSum = DataGridView1.ColumnHeadersHeight + DataGridView1.Rows(r).Height
rowCounter = 1
End If
If r = DataGridView1.Rows.Count - 2 Then
For x As Integer = 0 To maxPagesWide - 1
If pages(pageCounter + x).rows = 0 Then
pages(pageCounter + x) = New pageDetails With {.columns = pages(pageCounter + x).columns, .rows = rowCounter, .startCol = pages(pageCounter + x).startCol, .startRow = pages(pageCounter + x).startRow}
End If
Next
End If
Next
maxPagesTall = pages.Count \ maxPagesWide
End Sub
Private Sub PrintDocument1_PrintPage(ByVal sender As System.Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
Dim rect As New Rectangle(20, 20, CInt(PrintDocument1.DefaultPageSettings.PrintableArea.Width), Label1.Height)
Dim sf As New StringFormat
sf.Alignment = StringAlignment.Center
sf.LineAlignment = StringAlignment.Center
e.Graphics.DrawString(Label1.Text, Label1.Font, Brushes.Black, rect, sf)
sf.Alignment = StringAlignment.Near
Dim startX As Integer = 50
Dim startY As Integer = rect.Bottom
Static startPage As Integer = 0
For p As Integer = startPage To pages.Count - 1
Dim cell As New Rectangle(startX, startY, DataGridView1.RowHeadersWidth, DataGridView1.ColumnHeadersHeight)
e.Graphics.FillRectangle(New SolidBrush(SystemColors.ControlLight), cell)
e.Graphics.DrawRectangle(Pens.Black, cell)
startY += DataGridView1.ColumnHeadersHeight
For r As Integer = pages(p).startRow To pages(p).startRow + pages(p).rows - 1
cell = New Rectangle(startX, startY, DataGridView1.RowHeadersWidth, DataGridView1.Rows(r).Height)
e.Graphics.FillRectangle(New SolidBrush(SystemColors.ControlLight), cell)
e.Graphics.DrawRectangle(Pens.Black, cell)
e.Graphics.DrawString(DataGridView1.Rows(r).HeaderCell.Value, DataGridView1.Font, Brushes.Black, cell, sf)
startY += DataGridView1.Rows(r).Height
Next
startX += cell.Width
startY = rect.Bottom
For c As Integer = pages(p).startCol To pages(p).startCol + pages(p).columns - 1
If DataGridView1.Columns(c).Visible = True Then
cell = New Rectangle(startX, startY, DataGridView1.Columns(c).Width, DataGridView1.ColumnHeadersHeight)
e.Graphics.FillRectangle(New SolidBrush(SystemColors.ControlLight), cell)
e.Graphics.DrawRectangle(Pens.Black, cell)
e.Graphics.DrawString(DataGridView1.Columns(c).HeaderCell.Value, DataGridView1.Font, Brushes.Black, cell, sf)
startX += DataGridView1.Columns(c).Width
End If
Next
startY = rect.Bottom + DataGridView1.ColumnHeadersHeight
For r As Integer = pages(p).startRow To pages(p).startRow + pages(p).rows - 1
startX = 50 + DataGridView1.RowHeadersWidth
For c As Integer = pages(p).startCol To pages(p).startCol + pages(p).columns - 1
If DataGridView1.Columns(c).Visible = True Then
cell = New Rectangle(startX, startY, DataGridView1.Columns(c).Width, DataGridView1.Rows(r).Height)
e.Graphics.DrawRectangle(Pens.Black, cell)
e.Graphics.DrawString(DataGridView1(c, r).Value, DataGridView1.Font, Brushes.Black, cell, sf)
startX += DataGridView1.Columns(c).Width
End If
Next
startY += DataGridView1.Rows(r).Height
Next
If p <> pages.Count - 1 Then
startPage = p + 1
e.HasMorePages = True
Return
Else
startPage = 0
End If
Next
End Sub

Related

How do I hide a column when printing a DataGridView?

I have in the last of all rows of a DataGridView a "remove" button. I want to not show the remove button when I print it. How can I do this? Also I need to not show the place of the remove button.
I tried setting the Visible property of the column to False, but that did not hide the column from the printout.
Me.DataGridView1.Columns("Remove").Visible = False
With DataGridView1
Using fmt As New StringFormat With {
.Alignment = StringAlignment.Center,
.LineAlignment = StringAlignment.Center,
.Trimming = StringTrimming.EllipsisCharacter,
.FormatFlags = StringFormatFlags.LineLimit Or StringFormatFlags.NoWrap
}
Dim y As Single = e.MarginBounds.Top
Using headerFont As New Font("Arial", 12, FontStyle.Bold)
Do While mRow < .RowCount
Dim row As DataGridViewRow = .Rows(mRow)
Dim x As Single = e.MarginBounds.Left
Dim h As Single = 0
For Each cell As DataGridViewCell In row.Cells
Dim rc As RectangleF = New RectangleF(x, y, cell.Size.Width, cell.Size.Height)
If newpage Then
e.Graphics.DrawString(DataGridView1.Columns(cell.ColumnIndex).HeaderText, headerFont, Brushes.Black, rc, fmt) '
Else
e.Graphics.DrawString(DataGridView1.Rows(cell.RowIndex).Cells(cell.ColumnIndex).FormattedValue.ToString(), headerFont, Brushes.Black, rc, fmt)
End If
x += rc.Width
h = Math.Max(h, rc.Height)
Next
newpage = False
y += h
mRow += 1
If y + h > e.MarginBounds.Bottom Then
e.HasMorePages = True
mRow -= 1
newpage = True
Exit Sub
End If
Loop
End Using
End Using
mRow = 0
End With
If you find the index of the column you do not want to print, then you can check that index when iterating over the cells and simply skip over that iteration, something like this:
Me.DataGridView1.Columns("Remove").Visible = False
Dim skipRowNum = DataGridView1.Columns("Remove").Index
With DataGridView1
Using fmt As New StringFormat With {
.Alignment = StringAlignment.Center,
.LineAlignment = StringAlignment.Center,
.Trimming = StringTrimming.EllipsisCharacter,
.FormatFlags = StringFormatFlags.LineLimit Or StringFormatFlags.NoWrap
}
Dim y As Single = e.MarginBounds.Top
Using headerFont As New Font("Arial", 12, FontStyle.Bold)
Do While mRow < .RowCount
Dim row As DataGridViewRow = .Rows(mRow)
Dim x As Single = e.MarginBounds.Left
Dim h As Single = 0
For Each cell As DataGridViewCell In row.Cells
If cell.ColumnIndex = skipRowNum Then
Continue For
End If
Dim rc As RectangleF = New RectangleF(x, y, cell.Size.Width, cell.Size.Height)
If newPage Then
e.Graphics.DrawString(DataGridView1.Columns(cell.ColumnIndex).HeaderText, headerFont, Brushes.Black, rc, fmt) '
Else
e.Graphics.DrawString(DataGridView1.Rows(cell.RowIndex).Cells(cell.ColumnIndex).FormattedValue.ToString(), headerFont, Brushes.Black, rc, fmt)
End If
x += rc.Width
h = Math.Max(h, rc.Height)
Next
newPage = False
y += h
mRow += 1
If y + h > e.MarginBounds.Bottom Then
e.HasMorePages = True
mRow -= 1
newpage = True
Exit Sub
End If
Loop
End Using
End Using
mRow = 0
End With
You could easily extend that to exclude more than one column from being printed by using a List(Of Integer) for the columns to be skipped.
Dim skipRowNum = DataGridView1.Columns("Column1").Index
With DataGridView1
Using fmt As New StringFormat With {
.Alignment = StringAlignment.Center,
.LineAlignment = StringAlignment.Center,
.Trimming = StringTrimming.EllipsisCharacter,
.FormatFlags = StringFormatFlags.LineLimit Or StringFormatFlags.NoWrap
}
Dim y As Single = e.MarginBounds.Top
y = y + e.MarginBounds.Y + 30
Using headerFont As New Font("Arial", 12, FontStyle.Bold)
Do While mRow < .RowCount
Dim row As DataGridViewRow = .Rows(mRow)
Dim x As Single = e.MarginBounds.Left
Dim h As Single = 0
x = x + e.MarginBounds.X + 180
For Each cell As DataGridViewCell In row.Cells
If cell.ColumnIndex = skipRowNum Then
Continue For
End If
Dim rc As RectangleF = New RectangleF(x, y, cell.Size.Width, cell.Size.Height)
If newpage Then
e.Graphics.DrawString(DataGridView1.Columns(cell.ColumnIndex).HeaderText, headerFont, Brushes.Black, rc, fmt) '
Else
e.Graphics.DrawString(DataGridView1.Rows(cell.RowIndex).Cells(cell.ColumnIndex).FormattedValue.ToString(), headerFont, Brushes.Black, rc, fmt)
End If
x += rc.Width
h = Math.Max(h, rc.Height)
Next
newpage = False
y += h
mRow += 1
If y + h > e.MarginBounds.Bottom Then
e.HasMorePages = True
mRow -= 1
newpage = True
Exit Sub
End If
Loop
End Using
End Using
mRow = 0
End With

How I Do DataGridView Print Text Alignment Center and Font Size Change VB.NET

I have use the below code it work fine but how i large the font size and how i center text alignment please help me this code worked just center and font size problem this code work but the problem is how i alignment between two row
With DataGridView1
Using fmt As New StringFormat With {
.Alignment = StringAlignment.Center,
.LineAlignment = StringAlignment.Center,
.Trimming = StringTrimming.EllipsisCharacter,
.FormatFlags = StringFormatFlags.LineLimit Or StringFormatFlags.NoWrap
}
Dim y As Single = e.MarginBounds.Top
Using headerFont As New Font("Arial", 14, FontStyle.Bold)
Do While mRow < .RowCount
Dim row As DataGridViewRow = .Rows(mRow)
Dim x As Single = e.MarginBounds.Left
Dim h As Single = 0
For Each cell As DataGridViewCell In row.Cells
Dim rc As RectangleF = New RectangleF(x, y, cell.Size.Width, cell.Size.Height)
If newpage Then
e.Graphics.DrawString(DataGridView1.Columns(cell.ColumnIndex).HeaderText, headerFont, Brushes.Black, rc, fmt) '
Else
e.Graphics.DrawString(DataGridView1.Rows(cell.RowIndex).Cells(cell.ColumnIndex).FormattedValue.ToString(), headerFont, Brushes.Black, rc, fmt)
End If
x += rc.Width
h = Math.Max(h, rc.Height)
Next
newpage = False
y += h
mRow += 1
If y + h > e.MarginBounds.Bottom Then
e.HasMorePages = True
mRow -= 1
newpage = True
Exit Sub
End If
Loop
End Using
End Using
mRow = 0
End With

First row in DataGrid missing

I'm trying to output a data grid that retrieves user data and puts it in a table. When I try to do this, I believe the first row is replaced by the column name, then an additional empty row gets added to the bottom. Can anyone see any discrepancies with this code chunk that may cause it to do this?
Data Input:
Output Given:
Here's my code:
Dim mRow As Integer = 0
Dim newpage As Boolean = True
With DataGridViewONE
Dim fmt As StringFormat = New StringFormat(StringFormatFlags.LineLimit)
fmt.LineAlignment = StringAlignment.Center
fmt.Trimming = StringTrimming.EllipsisCharacter
Dim y As Single = 770 'e.MarginBounds.Top
Do While mRow < .RowCount
Dim row As DataGridViewRow = .Rows(mRow)
Dim x As Single = e.MarginBounds.Left
Dim h As Single = 1
For Each cell As DataGridViewCell In row.Cells
Dim rc As RectangleF = New RectangleF(x, y, cell.Size.Width, cell.Size.Height)
e.Graphics.DrawRectangle(Pens.Black, rc.Left, rc.Top, rc.Width, rc.Height)
If mRow = 0 Then
e.Graphics.DrawString(DataGridViewONE.Columns(cell.ColumnIndex).HeaderText,
.Font, Brushes.Black, rc, fmt)
Else
e.Graphics.DrawString(DataGridViewONE.Rows(cell.RowIndex).
Cells(cell.ColumnIndex).FormattedValue.ToString(),
.Font, Brushes.Black, rc, fmt)
End If
x += rc.Width
h = Math.Max(h, rc.Height)
Next
newpage = False
y += h
mRow += 1
If y + h > e.MarginBounds.Bottom Then
e.HasMorePages = True
mRow -= 1
newpage = True
Exit Sub
End If
Loop
mRow = 0
End With
EDIT
I have found that the ColumnIndex replaces the first row. Technically, if mRow was set to -1, there wouldn't be an issue, but doing so gives the error that index cannot be a negative value.
If mRow = 0 Then
e.Graphics.DrawString(DataGridViewONE.Columns(cell.ColumnIndex).HeaderText,
.Font, Brushes.Black, rc, fmt)
Replacing it with the Row DrawString would give the output I need but without the column headings

VB.net Printing text from a multiline textbox and several datagridviews after that

I am trying to print a multiline textbox and several different datagridviews after that. I hope some of the kind souls here would be able to help me.
So far, it works well when there is only one page from the datagridview, after that the last page of the text gets repeated.
Like so:
All Fine for Page 1
Problems afoot for every other page after that
To all who are about to read my code-mess, you have my utmost thanks.
Here's the code that I am using:
Dim mRow As Integer = 0
Dim newpage As Boolean = True
Dim page As Integer = 0
Dim tablepage As Integer = 0
Dim content1 As String
Dim numChars As Integer
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
PrintPreviewDialog1.Document = PrintDocument1
PrintPreviewDialog1.ShowDialog()
mRow = 0
newpage = True
page = 0
tablepage = 0
End Sub
Private Sub PrintDocument1_PrintPage(sender As Object, e As Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
Dim numLines As Integer
'1 Page
'TEXT
If page = 0 Then
content1 = TextBox6.Text & vbLf & TextBox7.Text & vbLf & TextBox8.Text
Dim stringForPage As String
Dim strFormat As New StringFormat()
Dim PrintFont As Font
PrintFont = TextBox6.Font
Dim rectDraw As New RectangleF(e.MarginBounds.Left, e.MarginBounds.Top, e.MarginBounds.Width, e.MarginBounds.Height)
Dim sizeMeasure As New SizeF(e.MarginBounds.Width, e.MarginBounds.Height - PrintFont.GetHeight(e.Graphics))
strFormat.Trimming = StringTrimming.Word
e.Graphics.MeasureString(content1, PrintFont, sizeMeasure, strFormat, numChars, numLines)
stringForPage = content1.Substring(0, numChars)
Dim rectDraw1 As New RectangleF(e.MarginBounds.Left, e.MarginBounds.Top, e.MarginBounds.Width, PrintFont.GetHeight(e.Graphics) * numLines)
e.Graphics.DrawString(stringForPage, PrintFont, Brushes.Black, rectDraw1, strFormat)
If numChars < content1.Length Then
content1 = content1.Substring(numChars)
e.HasMorePages = True
page += 1
Else
e.HasMorePages = False
'End If
'DATAGRIDVIEW
If tablepage > 0 Then
With TableDataGridView
Dim fmt As StringFormat = New StringFormat(StringFormatFlags.LineLimit)
fmt.LineAlignment = StringAlignment.Center
fmt.Trimming = StringTrimming.EllipsisCharacter
Dim y As Single = e.MarginBounds.Top '
Do While mRow < .RowCount
Dim row As DataGridViewRow = .Rows(mRow)
Dim x As Single = e.MarginBounds.Left
Dim h As Single = 0
For Each cell As DataGridViewCell In row.Cells
Dim rc As RectangleF = New RectangleF(x, y, cell.Size.Width, cell.Size.Height)
e.Graphics.DrawRectangle(Pens.Black, rc.Left, rc.Top, rc.Width, rc.Height)
If (newpage) Then
e.Graphics.DrawString(TableDataGridView.Columns(cell.ColumnIndex).HeaderText, .Font, Brushes.Black, rc, fmt)
Else
e.Graphics.DrawString(TableDataGridView.Rows(cell.RowIndex - 1).Cells(cell.ColumnIndex).FormattedValue.ToString(), .Font, Brushes.Black, rc, fmt)
End If
x += rc.Width
h = Math.Max(h, rc.Height)
Next
newpage = False
y += h
mRow += 1
If y + h > e.MarginBounds.Bottom Then ' 800 Then '
e.HasMorePages = True
newpage = True
mRow -= 1
Exit Sub
End If
Loop
End With
Else
'DATAGRIDVIEW < 2 page
With TableDataGridView
Dim fmt As StringFormat = New StringFormat(StringFormatFlags.LineLimit)
fmt.LineAlignment = StringAlignment.Center
fmt.Trimming = StringTrimming.EllipsisCharacter
Dim y As Single = 20 + rectDraw1.Bottom 'e.MarginBounds.Top '
Do While mRow < .RowCount
Dim row As DataGridViewRow = .Rows(mRow)
Dim x As Single = e.MarginBounds.Left
Dim h As Single = 0
For Each cell As DataGridViewCell In row.Cells
Dim rc As RectangleF = New RectangleF(x, y, cell.Size.Width, cell.Size.Height)
e.Graphics.DrawRectangle(Pens.Black, rc.Left, rc.Top, rc.Width, rc.Height)
If (newpage) Then
e.Graphics.DrawString(TableDataGridView.Columns(cell.ColumnIndex).HeaderText, .Font, Brushes.Black, rc, fmt)
Else
e.Graphics.DrawString(TableDataGridView.Rows(cell.RowIndex - 1).Cells(cell.ColumnIndex).FormattedValue.ToString(), .Font, Brushes.Black, rc, fmt)
End If
x += rc.Width
h = Math.Max(h, rc.Height)
Next
newpage = False
y += h
mRow += 1
If y + h > e.MarginBounds.Bottom Then '800 Then '
e.HasMorePages = True
newpage = True
mRow -= 1
tablepage += 1
Exit Sub
End If
Loop
End With
End If
End If
'TEXT
'More than 1 Page
ElseIf page > 0 Then
Dim stringForPage As String
Dim strFormat As New StringFormat()
Dim PrintFont As Font
PrintFont = TextBox6.Font
Dim rectDraw As New RectangleF(e.MarginBounds.Left, e.MarginBounds.Top, e.MarginBounds.Width, e.MarginBounds.Height)
Dim sizeMeasure As New SizeF(e.MarginBounds.Width, e.MarginBounds.Height - PrintFont.GetHeight(e.Graphics))
strFormat.Trimming = StringTrimming.Word
e.Graphics.MeasureString(content1, PrintFont, sizeMeasure, strFormat, numChars, numLines)
stringForPage = content1.Substring(0, numChars)
Dim rectDraw1 As New RectangleF(e.MarginBounds.Left, e.MarginBounds.Top, e.MarginBounds.Width, PrintFont.GetHeight(e.Graphics) * numLines)
e.Graphics.DrawString(stringForPage, PrintFont, Brushes.Black, rectDraw1, strFormat)
If numChars < content1.Length Then
content1 = content1.Substring(numChars)
e.HasMorePages = True
page += 1
Else
e.HasMorePages = False
'DATAGRIDVIEW
If tablepage > 0 Then
With TableDataGridView
Dim fmt As StringFormat = New StringFormat(StringFormatFlags.LineLimit)
fmt.LineAlignment = StringAlignment.Center
fmt.Trimming = StringTrimming.EllipsisCharacter
Dim y As Single = e.MarginBounds.Top '
Do While mRow < .RowCount
Dim row As DataGridViewRow = .Rows(mRow)
Dim x As Single = e.MarginBounds.Left
Dim h As Single = 0
For Each cell As DataGridViewCell In row.Cells
Dim rc As RectangleF = New RectangleF(x, y, cell.Size.Width, cell.Size.Height)
e.Graphics.DrawRectangle(Pens.Black, rc.Left, rc.Top, rc.Width, rc.Height)
If (newpage) Then
e.Graphics.DrawString(TableDataGridView.Columns(cell.ColumnIndex).HeaderText, .Font, Brushes.Black, rc, fmt)
Else
e.Graphics.DrawString(TableDataGridView.Rows(cell.RowIndex - 1).Cells(cell.ColumnIndex).FormattedValue.ToString(), .Font, Brushes.Black, rc, fmt)
End If
x += rc.Width
h = Math.Max(h, rc.Height)
Next
newpage = False
y += h
mRow += 1
If y + h > e.MarginBounds.Bottom Then ' 800 Then '
e.HasMorePages = True
newpage = True
mRow -= 1
Exit Sub
End If
Loop
End With
Else
'DATAGRIDVIEW < 2 page
With TableDataGridView
Dim fmt As StringFormat = New StringFormat(StringFormatFlags.LineLimit)
fmt.LineAlignment = StringAlignment.Center
fmt.Trimming = StringTrimming.EllipsisCharacter
Dim y As Single = 20 + rectDraw1.Bottom 'e.MarginBounds.Top '
Do While mRow < .RowCount
Dim row As DataGridViewRow = .Rows(mRow)
Dim x As Single = e.MarginBounds.Left
Dim h As Single = 0
For Each cell As DataGridViewCell In row.Cells
Dim rc As RectangleF = New RectangleF(x, y, cell.Size.Width, cell.Size.Height)
e.Graphics.DrawRectangle(Pens.Black, rc.Left, rc.Top, rc.Width, rc.Height)
If (newpage) Then
e.Graphics.DrawString(TableDataGridView.Columns(cell.ColumnIndex).HeaderText, .Font, Brushes.Black, rc, fmt)
Else
e.Graphics.DrawString(TableDataGridView.Rows(cell.RowIndex - 1).Cells(cell.ColumnIndex).FormattedValue.ToString(), .Font, Brushes.Black, rc, fmt)
End If
x += rc.Width
h = Math.Max(h, rc.Height)
Next
newpage = False
y += h
mRow += 1
If y + h > e.MarginBounds.Bottom Then '800 Then '
e.HasMorePages = True
newpage = True
mRow -= 1
tablepage += 1
Exit Sub
End If
Loop
End With
End If
End If
End If
End Sub
Instead of writing the same code over and over why not do something like
Static Pos AS Integer
For I = Pos To TableDataGridView.Rows.Count
'Do your graphics work here using TableDataGridView.Rows(i)
If y + h > e.MarginBounds.Bottom Then
Pos+=i
e.hasmorepages = true
Exit For
end if
next

how to create a multi-line label dynamically in vb.net

The scenario is i want to populate the label data dynamically based o the size of the string.say if the string length is 100 ,first 30 characters must be populated in first label,the remaining 30 on next label and so on.
what i have done so far
Dim remcontent, remcontentlength, remcontentlabelcount, labelcounter As New Integer
Dim rc As Integer = 30
Dim remcontentstring As String
remcontentlength = row.Item(4).ToString.Length
Dim endindex As Integer = 30
Dim startindex As Integer = 0
If remcontentlength > 30 Then
Dim actualremcontent As String
actualremcontent = "Note :" + row.Item(4).ToString
Dim modcheck As Integer
modcheck = remcontentlength Mod 30
If modcheck = 0 Then
remcontentlabelcount = (remcontentlength / 30)
Else
remcontentlabelcount = (Math.Floor(remcontentlength \ 30)) + 1
End If
ReDim remindercontantmulti(remcontentlabelcount)
For labelcounter = 1 To remcontentlabelcount
remindercontantmulti(labelcounter) = New Label
With remindercontantmulti(labelcounter)
.Name = "remindercontant " + x.ToString + labelcounter.ToString
.Text = actualremcontent.ToString.Substring(startindex, endindex)
.Visible = True
.Top = (22 * (x + (aa + 1))) + 10
.AutoSize = True
'.Left = reminderTime(x).Left + reminderTime(x).Width + 20
.BackColor = Color.Transparent
'.BorderStyle = BorderStyle.FixedSingle
.TextAlign = ContentAlignment.MiddleRight
.Font = New Drawing.Font("Trebuchet MS", 8, FontStyle.Regular)
Me.Panel4.Controls.Add(remindercontantmulti(labelcounter))
aa = aa + 1
End With
If Not startindex = 0 Then
startindex = startindex + rc
If (rc * labelcounter) < remcontentlength Then
endindex = remcontentlength - startindex
End If
End If
Next labelcounter
Else
remindercontant(x) = New Label
With remindercontant(x)
.Name = "remindercontant " + x.ToString
.Text = "Note :" + row.Item(4).ToString
.Visible = True
.Top = (22 * (x + (aa + 1))) + 10
.AutoSize = True
'.Left = reminderTime(x).Left + reminderTime(x).Width + 20
.BackColor = Color.Transparent
'.BorderStyle = BorderStyle.FixedSingle
.TextAlign = ContentAlignment.MiddleRight
.Font = New Drawing.Font("Trebuchet MS", 8, FontStyle.Regular)
Me.Panel4.Controls.Add(remindercontant(x))
aa = aa + 1
End With
End If