📄 datagridprinter.vb
字号:
'\\ Set this column's width
Dim rcCell As Rectangle = _DataGrid.GetCellBounds(0, nColumn)
If rcCell.Width > 0 Then
rcCell.Width = rcCell.Width - 1
NextColumn.Width = (rcCell.Width / TotalWidth) * TotalWidthOfAllPages
If NextColumn.Width > e.MarginBounds.Width Then
NextColumn.Width = e.MarginBounds.Width
End If
End If
If _ColumnBounds.RightExtents + NextColumn.Width > (e.MarginBounds.Left + e.MarginBounds.Width) Then
_ColumnBounds.NextPage()
NextColumn.Left = e.MarginBounds.Left
End If
_ColumnBounds.Add(NextColumn)
Next
If _ColumnBounds.TotalPages > Me.PagesAcross Then
Me.PagesAcross = _ColumnBounds.TotalPages
End If
End If
'\\ Print the document header
Call PrintHeader(e)
'\\ Print as many grid lines as can fit
Dim nextLine As Int32
Call PrintGridHeaderLine(e)
Dim StartOfpage As Integer = _CurrentPrintGridLine
For nextLine = _CurrentPrintGridLine To Min((_CurrentPrintGridLine + RowsPerPage(_PrintFont, e.Graphics)), CType(_DataGrid.DataSource, System.Data.DataTable).DefaultView.Count)
Call PrintGridLine(e, nextLine)
Next
_CurrentPrintGridLine = nextLine
'\\ Print the document footer
Call PrintFooter(e)
If _CurrentPageAcross = PagesAcross Then
_CurrentPageAcross = 1
_CurrentPageDown += 1
Else
_CurrentPageAcross += 1
_CurrentPrintGridLine = StartOfpage
End If
'\\ If there are more lines to print, set the HasMorePages property to true
If _CurrentPrintGridLine < GridRowCount() Then
e.HasMorePages = True
End If
End Sub
#End Region
#Region "Private methods"
Private Sub PrintHeader(ByVal e As System.Drawing.Printing.PrintPageEventArgs)
If _HeaderRectangle.Height > 0 Then
e.Graphics.FillRectangle(_HeaderBrush, _HeaderRectangle)
e.Graphics.DrawRectangle(_HeaderPen, _HeaderRectangle)
Call DrawCellString(_HeaderText, CellTextHorizontalAlignment.CentreAlign, CellTextVerticalAlignment.MiddleAlign, _HeaderRectangle, False, e.Graphics, _HeaderFont, _HeaderBrush)
End If
End Sub
Private Sub PrintFooter(ByVal e As System.Drawing.Printing.PrintPageEventArgs)
If _FooterRectangle.Height > 0 Then
e.Graphics.FillRectangle(_FooterBrush, _FooterRectangle)
e.Graphics.DrawRectangle(_FooterPen, _FooterRectangle)
Call DrawCellString("Printed by " & _LoggedInUsername, CellTextHorizontalAlignment.LeftAlign, CellTextVerticalAlignment.MiddleAlign, _FooterRectangle, False, e.Graphics, _PrintFont, Brushes.White)
Call DrawCellString(DateTime.Now.ToLongDateString, CellTextHorizontalAlignment.CentreAlign, CellTextVerticalAlignment.MiddleAlign, _FooterRectangle, False, e.Graphics, _PrintFont, Brushes.White)
Call DrawCellString("Page " & (((_CurrentPageDown - 1) * PagesAcross) + _CurrentPageAcross).ToString, CellTextHorizontalAlignment.RightAlign, CellTextVerticalAlignment.MiddleAlign, _FooterRectangle, False, e.Graphics, _PrintFont, Brushes.White)
End If
End Sub
Private Sub PrintGridLine(ByVal e As System.Drawing.Printing.PrintPageEventArgs, ByVal RowNumber As Integer)
Dim RowFromTop As Integer = RowNumber + 1 - _CurrentPrintGridLine
Dim Top As Double = _PageContentRectangle.Top + (RowFromTop * ((_CellGutter * 2) + _Rowheight))
Dim Bottom As Double = Top + _Rowheight + (2 * _CellGutter)
Top = RoundTo(Top, 2)
Bottom = RoundTo(Bottom, 2)
Dim Items() As Object
Try
If TypeOf _DataGrid.DataSource Is DataTable Then
Items = CType(_DataGrid.DataSource, System.Data.DataTable).DefaultView.Item(RowNumber - 1).Row.ItemArray
ElseIf TypeOf _DataGrid.DataSource Is DataSet Then
Items = CType(_DataGrid.DataSource, System.Data.DataSet).Tables(_DataGrid.DataMember).DefaultView.Item(RowNumber - 1).Row.ItemArray
ElseIf TypeOf _DataGrid.DataSource Is DataView Then
Items = CType(_DataGrid.DataSource, System.Data.DataView).Table.DefaultView.Item(RowNumber - 1).Row.ItemArray
Else
'TODO : Get the content for the current row ....
End If
Dim RowBrush As Brush
If ((RowNumber Mod 2) = 0) Then
RowBrush = _OddRowBrush
Else
RowBrush = _EvenRowBrush
End If
Dim nColumn As Integer
For nColumn = 0 To Items.Length - 1
If _ColumnBounds(nColumn).Page = _CurrentPageAcross Then
Dim rcCell As New Rectangle(CInt(_ColumnBounds(nColumn).Left), CInt(Top), CInt(_ColumnBounds(nColumn).Width), CInt(Bottom - Top))
If rcCell.Width > 0 Then
Dim Columntext As String
Try
Columntext = Convert.ToString(Items(MappedColumnToBaseColumn(nColumn)))
Catch
End Try
Call DrawCellString(Columntext, CellTextHorizontalAlignment.CentreAlign, CellTextVerticalAlignment.MiddleAlign, rcCell, True, e.Graphics, _PrintFont, RowBrush)
End If
End If
Next
Catch exIndex As Exception
Trace.WriteLine(exIndex.ToString, Me.GetType.ToString)
End Try
End Sub
Private Sub PrintGridHeaderLine(ByVal e As System.Drawing.Printing.PrintPageEventArgs)
Dim Top As Double = _PageContentRectangle.Top
Dim Bottom As Double = Top + _Rowheight + (2 * _CellGutter)
Top = RoundTo(Top, 2)
Bottom = RoundTo(Bottom, 2)
Dim nColumn As Integer
For nColumn = 0 To GridColumnCount() - 1
If _ColumnBounds(nColumn).Page = _CurrentPageAcross Then
Dim rcCell As New Rectangle(CInt(_ColumnBounds(nColumn).Left), CInt(Top), CInt(_ColumnBounds(nColumn).Width), CInt(Bottom - Top))
If rcCell.Width > 0 Then
Call DrawCellString(GetColumnHeadingText(nColumn), CellTextHorizontalAlignment.CentreAlign, CellTextVerticalAlignment.MiddleAlign, rcCell, True, e.Graphics, _PrintFont, _ColumnHeaderBrush)
End If
End If
Next
End Sub
Private Function RowsPerPage(ByVal GridLineFont As Font, ByVal e As Graphics) As Integer
Return CInt((_PageContentRectangle.Height / ((_CellGutter * 2) + _Rowheight)) - 2)
End Function
Public Sub DrawCellString(ByVal s As String, _
ByVal HorizontalAlignment As CellTextHorizontalAlignment, _
ByVal VerticalAlignment As CellTextVerticalAlignment, _
ByVal BoundingRect As Rectangle, _
ByVal DrawRectangle As Boolean, _
ByVal Target As Graphics, _
ByVal PrintFont As Font, _
ByVal FillColour As Brush)
Dim x As Single, y As Single
If DrawRectangle Then
Target.FillRectangle(FillColour, BoundingRect)
Target.DrawRectangle(_GridPen, BoundingRect)
End If
'\\ Set the text alignment
If HorizontalAlignment = CellTextHorizontalAlignment.LeftAlign Then
_Textlayout.Alignment = StringAlignment.Near
ElseIf HorizontalAlignment = CellTextHorizontalAlignment.RightAlign Then
_Textlayout.Alignment = StringAlignment.Far
Else
_Textlayout.Alignment = StringAlignment.Center
End If
Dim BoundingRectF As New RectangleF(BoundingRect.X + _CellGutter, BoundingRect.Y + _CellGutter, BoundingRect.Width - (2 * _CellGutter), BoundingRect.Height - (2 * _CellGutter))
Target.DrawString(s, PrintFont, System.Drawing.Brushes.Black, BoundingRectF, _Textlayout)
End Sub
'\\ --[RoundTo]-----------------------------------------------------------------------------
'\\ Rounds the input number tot he nearest modulus of NearsetMultiple
'\\ ----------------------------------------------------------------------------------------
Private Function RoundTo(ByVal Input As Double, ByVal NearestMultiple As Integer) As Integer
If ((Input Mod NearestMultiple) > (NearestMultiple / 2)) Then
Return ((CInt(Input) \ NearestMultiple) * NearestMultiple) + NearestMultiple
Else
Return (CInt(Input) \ NearestMultiple) * NearestMultiple
End If
End Function
'\\ --[Min]------------------------------------------------------------
'\\ Returns the minimum of two numbers
'\\ -------------------------------------------------------------------
Private Function Min(ByVal a As Integer, ByVal b As Integer) As Integer
If a < b Then
Return a
Else
Return b
End If
End Function
Private Function GridColumnCount() As Integer
If _GridColumnCount = 0 Then
If TypeOf _DataGrid.DataSource Is DataTable Then
_GridColumnCount = CType(_DataGrid.DataSource, DataTable).Columns.Count
ElseIf TypeOf _DataGrid.DataSource Is DataSet Then
_GridColumnCount = CType(_DataGrid.DataSource, DataSet).Tables(_DataGrid.DataMember).Columns.Count
ElseIf TypeOf _DataGrid.DataSource Is DataView Then
_GridColumnCount = CType(_DataGrid.DataSource, DataView).Table.Columns.Count
Else
'TODO : Get the column count....
End If
End If
Return _GridColumnCount
End Function
Private Function GridRowCount() As Integer
If _GridRowCount = 0 Then
If TypeOf _DataGrid.DataSource Is DataTable Then
_GridRowCount = CType(_DataGrid.DataSource, DataTable).DefaultView.Count
ElseIf TypeOf _DataGrid.DataSource Is DataSet Then
_GridRowCount = CType(_DataGrid.DataSource, DataSet).Tables(_DataGrid.DataMember).DefaultView.Count
ElseIf TypeOf _DataGrid.DataSource Is DataView Then
_GridRowCount = CType(_DataGrid.DataSource, DataView).Table.DefaultView.Count
Else
'TODO : Get the column count....
End If
End If
Return _GridRowCount
End Function
Private Function GetColumnHeadingText(ByVal Column As Integer) As String
If _DataGrid.TableStyles.Count > 0 Then
Return _DataGrid.TableStyles(_DataGrid.TableStyles.Count - 1).GridColumnStyles(Column).HeaderText
Else
If TypeOf _DataGrid.DataSource Is DataTable Then
Return CType(_DataGrid.DataSource, DataTable).Columns(Column).Caption
ElseIf TypeOf _DataGrid.DataSource Is DataSet Then
Return CType(_DataGrid.DataSource, DataSet).Tables(0).Columns(Column).Caption
ElseIf TypeOf _DataGrid.DataSource Is DataView Then
Return CType(_DataGrid.DataSource, DataView).Table.Columns(Column).Caption
End If
End If
End Function
Private Function MappedColumnToBaseColumn(ByVal MappedColumn As Integer) As Integer
If _DataGrid.TableStyles.Count <= 1 Then
Return MappedColumn
Else
'\\ Need to map from the column in the default to the column in the active map..
Return _DataGrid.TableStyles(0).GridColumnStyles.IndexOf(_DataGrid.TableStyles(_DataGrid.TableStyles.Count - 1).GridColumnStyles(MappedColumn))
End If
End Function
#End Region
#Region "Public constructors"
Public Sub New(ByVal Grid As DataGrid)
'\\ Initialise the bits we need to use later
_GridPrintDocument = New PrintDocument
_DataGrid = Grid
Dim LoggedInuser As New WindowsPrincipal(WindowsIdentity.GetCurrent())
_LoggedInUsername = DataGridPrinter.StripDomainFromFullUsername(WindowsIdentity.GetCurrent.Name)
End Sub
#End Region
End Class
#End Region
#Region "ColumnBound"
Public Class ColumnBound
#Region "Private properties"
Private _Page As Integer = 1
Private _Left As Double
Private _Width As Double
#End Region
#Region "Public interface"
Public Property Left() As Double
Get
Return _Left
End Get
Set(ByVal value As Double)
If value < 0 Then
Throw New ArgumentException("Left must be greater than zero")
End If
_Left = value
End Set
End Property
Public Property Width() As Double
Get
Return _Width
End Get
Set(ByVal Value As Double)
If Value < 0 Then
Throw New ArgumentException("Width must be greater than zero")
End If
_Width = Value
End Set
End Property
Public Property Page() As Integer
Get
Return _Page
End Get
Set(ByVal Value As Integer)
If Value < 1 Then
Throw New ArgumentOutOfRangeException("Page", "Must be greater than zero")
End If
_Page = Value
End Set
End Property
#End Region
End Class
#End Region
#Region "ColumnBounds"
'\\ Type safe collection of "ColumnBound" objects
Public Class ColumnBounds
Inherits System.Collections.ArrayList
#Region "Private properties"
Private _CurrentPage As Integer = 1
Private _RightExtents As Double '\\ How far right does this column set reach?
#End Region
#Region "ArrayList overrides"
Public Overloads Function Add(ByVal ColumnBound As ColumnBound) As Integer
If ColumnBound.Left + ColumnBound.Width > _RightExtents Then
_RightExtents = ColumnBound.Left + ColumnBound.Width
End If
ColumnBound.Page = _CurrentPage
Return MyBase.Add(ColumnBound)
End Function
Public Overloads Sub Clear()
_CurrentPage = 1
_RightExtents = 0
MyBase.Clear()
End Sub
Public Sub NextPage()
_CurrentPage += 1
_RightExtents = 0
End Sub
Friend ReadOnly Property TotalPages() As Integer
Get
Return _CurrentPage
End Get
End Property
Default Public Shadows Property Item(ByVal Index As Integer) As ColumnBound
Get
Return CType(MyBase.Item(Index), ColumnBound)
End Get
Set(ByVal Value As ColumnBound)
MyBase.Item(Index) = Value
End Set
End Property
#End Region
#Region "Public interface"
Public ReadOnly Property RightExtents() As Double
Get
Return _RightExtents
End Get
End Property
#End Region
End Class
#End Region
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -