📄 datagridprinter.vb
字号:
Imports System.Drawing.Printing
Public Class DataGridPrinter
Public RowCount As Integer = 0
Public PageNumber As Integer = 1
Private m_DataTable As DataTable
Private m_DataGrid As DataGrid
Private m_ImageArray(2) As Image
Private m_PageWidth As Integer
Private m_PageWidthMinusMargins As Integer
Private m_PageHeight As Integer
Private m_AdjColumnBy As Integer
Private m_IsTooWide As Boolean
Private m_DataGridWidth As Integer
Private Const c_TopMargin As Integer = 50
Private Const c_BottomMargin As Integer = 50
Private Const c_LeftMargin As Integer = 50
Private Const c_RightMargin As Integer = 50
Private Const c_VerticalCellLeeway As Integer = 10
Public Sub New(ByVal dg As DataGrid, ByVal pd As PrintDocument, ByVal dt As DataTable)
m_DataGrid = dg
m_DataTable = dt
'set the document as landscape
pd.DefaultPageSettings.Landscape = True
'extract our width and height values
m_PageHeight = pd.DefaultPageSettings.PaperSize.Width
m_PageWidth = pd.DefaultPageSettings.PaperSize.Height
m_PageWidthMinusMargins = m_PageWidth - (c_LeftMargin + c_RightMargin)
'hard-coded images
m_ImageArray(0) = Image.FromFile("images/major.gif")
m_ImageArray(1) = Image.FromFile("images/medium.gif")
m_ImageArray(2) = Image.FromFile("images/minor.gif")
m_DataGridWidth = GetDataGridWidth()
'set up some adjustments to scale the output later
If m_DataGrid.Width > m_PageWidthMinusMargins Then
m_AdjColumnBy = m_DataGrid.Width - m_PageWidthMinusMargins
m_DataGridWidth = m_DataGridWidth - m_AdjColumnBy
m_IsTooWide = True
Else
m_AdjColumnBy = m_PageWidthMinusMargins - m_DataGrid.Width
m_DataGridWidth = m_DataGridWidth + m_AdjColumnBy
m_IsTooWide = False
End If
End Sub
Public Function DrawDataGrid(ByVal g As Graphics) As Boolean
Try
DrawPageHeader(g)
Return DrawPageRows(g)
Catch ex As Exception
MessageBox.Show(ex.Message.ToString())
Return False
End Try
End Function
Private Sub DrawPageHeader(ByVal g As Graphics)
'create the header rectangle
Dim headerBounds As New RectangleF(c_LeftMargin, c_TopMargin, m_PageWidthMinusMargins, m_DataGrid.HeaderFont.SizeInPoints + c_VerticalCellLeeway)
'draw the header rectangle
g.FillRectangle(New SolidBrush(m_DataGrid.HeaderBackColor), headerBounds)
Dim xPosition As Single = c_LeftMargin + 12 ' +12 for some padding
'use this format when drawing later
Dim cellFormat As New StringFormat()
cellFormat.Trimming = StringTrimming.Word
cellFormat.FormatFlags = StringFormatFlags.NoWrap Or StringFormatFlags.LineLimit
'find the column names from the tablestyle
Dim cs As DataGridColumnStyle
For Each cs In m_DataGrid.TableStyles(0).GridColumnStyles
If cs.Width > 0 Then
'temp width to draw this column
Dim columnWidth As Integer = cs.Width
'scale the summary column width
'note: just a quick way to fit the text to the page width
'this is not the best way to do this but it handles the most
'common ui path for this demo app
If cs.MappingName = "TaskSummary" And m_IsTooWide Then
columnWidth -= m_AdjColumnBy
ElseIf cs.MappingName = "TaskSummary" Then
columnWidth += m_AdjColumnBy
End If
'create a layout rectangle to draw within.
Dim cellBounds As New RectangleF(xPosition, c_TopMargin, columnWidth, m_DataGrid.HeaderFont.SizeInPoints + c_VerticalCellLeeway)
'draw the column name
g.DrawString(cs.HeaderText, m_DataGrid.HeaderFont, New SolidBrush(m_DataGrid.HeaderForeColor), cellBounds, cellFormat)
'adjust the next X Pos
xPosition += columnWidth
End If
Next
End Sub
Private Function DrawPageRows(ByVal g As Graphics) As Boolean
Dim yPosition As Single = c_TopMargin + m_DataGrid.HeaderFont.SizeInPoints + (c_VerticalCellLeeway * 2)
'use this format when drawing later
Dim cellFormat As New StringFormat()
cellFormat.Trimming = StringTrimming.Word
cellFormat.FormatFlags = StringFormatFlags.NoWrap Or StringFormatFlags.LineLimit
'loop each visible row
Dim i As Integer = 0
For i = RowCount To (m_DataTable.DefaultView.Count - 1)
Dim xPosition As Single = c_LeftMargin + 12 ' +12 for some padding
'loop the columns of this row, if the column is visible
'then print the cell value
Dim cs As DataGridColumnStyle
For Each cs In m_DataGrid.TableStyles(0).GridColumnStyles
If cs.Width > 0 Then
'temp width to draw this column
Dim columnWidth As Integer = cs.Width
'scale the summary column width
'note: just a quick way to fit the text to the page width
'this is not the best way to do this but it handles the most
'common ui path for this demo app
If cs.MappingName = "TaskSummary" And m_IsTooWide Then
columnWidth -= m_AdjColumnBy
ElseIf cs.MappingName = "TaskSummary" Then
columnWidth += m_AdjColumnBy
End If
'create a layout rectangle to draw within.
Dim cellBounds As New RectangleF(xPosition, yPosition, columnWidth, m_DataGrid.Font.SizeInPoints + c_VerticalCellLeeway)
'draw the item value
If cs.MappingName = "PriorityText" Then
'draw image
Select Case m_DataTable.DefaultView.Item(i).Item("PriorityText")
Case "Major"
g.DrawImage(m_ImageArray(0), New Point(Convert.ToInt32(cellBounds.X) - 5, Convert.ToInt32(cellBounds.Y)))
Case "Medium"
g.DrawImage(m_ImageArray(1), New Point(Convert.ToInt32(cellBounds.X) - 5, Convert.ToInt32(cellBounds.Y)))
Case "Minor"
g.DrawImage(m_ImageArray(2), New Point(Convert.ToInt32(cellBounds.X) - 5, Convert.ToInt32(cellBounds.Y)))
End Select
Else
'draw as short date format or regular string
If m_DataTable.DefaultView.Item(i).Item(cs.MappingName).GetType() Is GetType(DateTime) Then
g.DrawString(String.Format("{0:d}", m_DataTable.DefaultView.Item(i).Item(cs.MappingName)), m_DataGrid.Font, New SolidBrush(m_DataGrid.HeaderForeColor), cellBounds, cellFormat)
Else
g.DrawString(CType(m_DataTable.DefaultView.Item(i).Item(cs.MappingName), String), m_DataGrid.Font, New SolidBrush(m_DataGrid.HeaderForeColor), cellBounds, cellFormat)
End If
End If
'adjust the next X Pos
xPosition += columnWidth
End If
Next
'set the rowcount (which is used for a possible next page)
RowCount += 1
'finished with this row, draw a nice line
g.DrawLine(New Pen(m_DataGrid.GridLineColor, 1), c_LeftMargin, yPosition + m_DataGrid.HeaderFont.SizeInPoints + c_VerticalCellLeeway - 2, m_PageWidthMinusMargins + c_LeftMargin, yPosition + m_DataGrid.HeaderFont.SizeInPoints + c_VerticalCellLeeway - 1)
'adjust the next Y Pos
yPosition += m_DataGrid.HeaderFont.SizeInPoints + c_VerticalCellLeeway + 3
'if at end of page exit out for next page
If yPosition * PageNumber > PageNumber * (m_PageHeight - (c_BottomMargin + c_TopMargin)) Then
Return True
End If
Next
Return False
End Function
Private Function GetDataGridWidth() As Integer
Try
Dim cs As DataGridColumnStyle
Dim dgWidth As Integer = 0
For Each cs In m_DataGrid.TableStyles(0).GridColumnStyles
If cs.Width <> 0 Then
dgWidth = dgWidth + cs.Width
End If
Next
Return dgWidth
Catch ex As Exception
LogError.Write(ex.Message & vbNewLine & ex.StackTrace)
Throw ex
End Try
End Function
End Class
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -