When you click the program's button, it displays a print preview dialog. The dialog raises a PrintDocument object's PrintPage event, which executes the following code.
The code starts by defining some test headers and data. It then loops through the headers and data to see how big each item will be and keeps track of the widest item in each column. Subeoutine CheckColWidths makes this easier by checking each column for one row of values.
Next the code examines the items in the first row of data. If an item is an integer, single, or double, the code sets the column's alignment to Far (right). Otherwise it sets the column's alignment to Near (left).
The code then adds up the widths of all columns, adding an extra margin on both sides of each column.
The program then fills the header area with black and draws the header text in white.
Finally the code prints the values. For each row, it fills the row's area with an alternating color and then draws the row's values.
|
Private Sub PrintDocument1_PrintPage(ByVal sender As _
System.Object, ByVal e As _
System.Drawing.Printing.PrintPageEventArgs) Handles _
PrintDocument1.PrintPage
' Some bogus data.
Dim headers() As String = {"Fruit", "Vegetable", _
"Price"}
Dim values() As Object = { _
New Object() {"Apple", "Artichoke", 12.45}, _
New Object() {"Banana", "Bean", 19.95}, _
New Object() {"Cherry", "Corn", 1.23}, _
New Object() {"Date", "Donut", 0.45}, _
New Object() {"Egg", "Eclair", 19.95}, _
New Object() {"Fig", "Fruit cup", 1.23} _
}
' See how wide the columns need to be.
Dim num_rows As Integer = values.Length
Dim num_cols As Integer = values(0).Length
Dim col_wid(num_cols - 1) As Integer
Dim header_font As New Font("Times New Roman", 18, _
FontStyle.Bold)
CheckColWidths(col_wid, e.Graphics, header_font, _
headers)
Dim value_font As New Font("Times New Roman", 16)
For Each row() As Object In values
CheckColWidths(col_wid, e.Graphics, value_font, row)
Next row
For i As Integer = 0 To num_cols - 1
col_wid(i) += 20
Next i
' Define column alignments.
Dim alignments(num_cols - 1) As StringAlignment
For i As Integer = 0 To num_cols - 1
If TypeOf values(0)(i) Is Integer Or _
TypeOf values(0)(i) Is Single Or _
TypeOf values(0)(i) Is Double _
Then
alignments(i) = StringAlignment.Far
Else
alignments(i) = StringAlignment.Near
End If
Next i
Const HEADER_MARGIN As Integer = 5
Const COL_MARGIN As Integer = 5
Const ROW_HGT As Integer = 30
' Get the total width.
Dim grid_wid As Integer = 0
For i As Integer = 0 To num_cols - 1
grid_wid += col_wid(i) + 2 * COL_MARGIN
Next i
' Print the headers.
Dim x As Integer = e.MarginBounds.Left
Dim y As Integer = e.MarginBounds.Top
' Fill the header's background.
Dim bg_rect As New Rectangle( _
x, y, grid_wid, ROW_HGT + HEADER_MARGIN)
e.Graphics.FillRectangle(Brushes.Black, bg_rect)
' Draw the header text.
For i As Integer = 0 To headers.Length - 1
Dim layout_rect As New _
RectangleF(x + COL_MARGIN, y, col_wid(i), _
ROW_HGT)
Dim string_format As New StringFormat
string_format.Alignment = alignments(i)
string_format.LineAlignment = StringAlignment.Near
e.Graphics.DrawString(headers(i), _
header_font, Brushes.White, _
layout_rect, string_format)
x += col_wid(i) + 2 * COL_MARGIN
Next i
bg_rect.Height -= HEADER_MARGIN
y += HEADER_MARGIN
' Print the values.
Dim max_x As Integer = x
For r As Integer = 0 To num_rows - 1
x = e.MarginBounds.Left
y += ROW_HGT
' Fill the row's background.
bg_rect.Y = y
If r Mod 2 = 0 Then
e.Graphics.FillRectangle(Brushes.LightGray, _
bg_rect)
Else
e.Graphics.FillRectangle(Brushes.Gray, bg_rect)
End If
For i As Integer = 0 To num_cols - 1
' Draw the text.
Dim layout_rect As New _
RectangleF(x + COL_MARGIN, y, col_wid(i), _
ROW_HGT)
Dim string_format As New StringFormat
string_format.Alignment = alignments(i)
string_format.LineAlignment = _
StringAlignment.Near
e.Graphics.DrawString(values(r)(i), _
value_font, Brushes.Black, _
layout_rect, string_format)
x += col_wid(i) + 2 * COL_MARGIN
Next i
e.Graphics.DrawLine(Pens.Black, _
e.MarginBounds.X, y, max_x, y)
Next r
' Draw grid lines.
Dim grid_hgt As Integer = (values.Length + 1) * ROW_HGT _
+ HEADER_MARGIN
e.Graphics.DrawRectangle(Pens.Black, _
e.MarginBounds.X, e.MarginBounds.Y, _
max_x - e.MarginBounds.X, grid_hgt)
End Sub
|