293 lines
17 KiB
VB.net
293 lines
17 KiB
VB.net
Imports System.Collections.Generic
|
|
Imports Microsoft.VisualBasic.PowerPacks.Printing
|
|
Imports System.Data.Common
|
|
|
|
Public Class PrintDGV
|
|
Private Shared StrFormat As StringFormat ' Holds content of a TextBox Cell to write by DrawString
|
|
Private Shared StrFormatComboBox As StringFormat ' Holds content of a Boolean Cell to write by DrawImage
|
|
Private Shared CellButton As Button ' Holds the Contents of Button Cell
|
|
Private Shared CellCheckBox As CheckBox ' Holds the Contents of CheckBox Cell
|
|
Private Shared CellComboBox As ComboBox ' Holds the Contents of ComboBox Cell
|
|
Private Shared TotalWidth As Int16 ' Summation of Columns widths
|
|
Private Shared RowPos As Int16 ' Position of currently printing row
|
|
Private Shared NewPage As Boolean ' Indicates if a new page reached
|
|
Private Shared PageNo As Int16 ' Number of pages to print
|
|
Private Shared ColumnLefts As New ArrayList ' Left Coordinate of Columns
|
|
Private Shared ColumnWidths As New ArrayList ' Width of Columns
|
|
Private Shared ColumnTypes As New ArrayList ' DataType of Columns
|
|
Private Shared CellHeight As Int16 ' Height of DataGrid Cell
|
|
Private Shared RowsPerPage As Int16 ' Number of Rows per Page
|
|
Private Shared WithEvents PrintDoc As New System.Drawing.Printing.PrintDocument ' PrintDocumnet Object used for printing
|
|
Private Shared PrintTitle As String = "" ' Header of pages
|
|
Private Shared dgv As DataGridView ' Holds DataGrid Object to print its contents
|
|
Private Shared SelectedColumns As New List(Of String) ' The Columns Selected by user to print.
|
|
Private Shared AvailableColumns As New List(Of String) ' All Columns avaiable in DataGrid
|
|
Private Shared PrintAllRows As Boolean = True ' True = print all rows, False = print selected rows
|
|
Private Shared FitToPageWidth As Boolean = True ' True = Fits selected columns to page width , False = Print columns as showed
|
|
Private Shared HeaderHeight As Int16 = 0
|
|
Private Shared drawfont As New Font("Arial", 7) ''<-------------------------------------------------------------------8
|
|
Private Shared drawfont1 As New Font("Arial", 6, FontStyle.Bold)
|
|
|
|
Public Shared Sub Print_DataGridView(ByVal DataGridView1 As DataGridView)
|
|
Dim ppvw As PrintPreviewDialog
|
|
Try
|
|
' Getting DataGridView object to print
|
|
dgv = DataGridView1
|
|
' Getting all Coulmns Names in the DataGridView
|
|
AvailableColumns.Clear()
|
|
For Each c As DataGridViewColumn In dgv.Columns
|
|
If Not c.Visible Then Continue For
|
|
AvailableColumns.Add(c.HeaderText)
|
|
Next
|
|
' Showing the PrintOption Form
|
|
'Dim dlg As New PrintOptions(AvailableColumns)
|
|
'If dlg.ShowDialog() <> DialogResult.OK Then Exit Sub
|
|
' Saving some printing attributes
|
|
' PrintTitle = ReporTitleAsNeeded ' dlg.PrintTitle
|
|
PrintAllRows = True ' dlg.PrintAllRows
|
|
FitToPageWidth = True ' dlg.FitToPageWidth
|
|
SelectedColumns = AvailableColumns 'dlg.GetSelectedColumns
|
|
'RowsPerPage = 0
|
|
Dim psd As New PageSetupDialog()
|
|
psd.Document = PrintDoc
|
|
psd.PageSettings.Landscape = True
|
|
psd.ShowDialog()
|
|
PrintDoc.DefaultPageSettings = psd.PageSettings
|
|
PrintDoc.DefaultPageSettings.Landscape = True
|
|
ppvw = New PrintPreviewDialog
|
|
ppvw.Document = PrintDoc
|
|
' Showing the Print Preview Page
|
|
If ppvw.ShowDialog() <> DialogResult.OK Then Exit Sub
|
|
|
|
|
|
PrintDoc.Print()
|
|
Catch ex As Exception
|
|
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
|
|
Finally
|
|
End Try
|
|
End Sub
|
|
Private Shared Sub PrintDoc_BeginPrint(ByVal sender As Object,
|
|
ByVal e As System.Drawing.Printing.PrintEventArgs) Handles PrintDoc.BeginPrint
|
|
Try
|
|
' Formatting the Content of Text Cells to print
|
|
StrFormat = New StringFormat
|
|
StrFormat.Alignment = StringAlignment.Near
|
|
StrFormat.LineAlignment = StringAlignment.Center
|
|
StrFormat.Trimming = StringTrimming.EllipsisCharacter
|
|
' Formatting the Content of Combo Cells to print
|
|
StrFormatComboBox = New StringFormat
|
|
StrFormatComboBox.LineAlignment = StringAlignment.Center
|
|
StrFormatComboBox.FormatFlags = StringFormatFlags.NoWrap
|
|
StrFormatComboBox.Trimming = StringTrimming.EllipsisCharacter
|
|
ColumnLefts.Clear()
|
|
ColumnWidths.Clear()
|
|
ColumnTypes.Clear()
|
|
CellHeight = 0
|
|
RowsPerPage = 0
|
|
' For various column types
|
|
CellButton = New Button
|
|
CellCheckBox = New CheckBox
|
|
CellComboBox = New ComboBox
|
|
TotalWidth = 0
|
|
For Each GridCol As DataGridViewColumn In dgv.Columns
|
|
If Not GridCol.Visible Then Continue For
|
|
If Not SelectedColumns.Contains(GridCol.HeaderText) Then Continue For
|
|
TotalWidth += GridCol.Width
|
|
Next
|
|
PageNo = 1
|
|
NewPage = True
|
|
RowPos = 0
|
|
Catch ex As Exception
|
|
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
|
|
Finally
|
|
End Try
|
|
End Sub
|
|
Private Shared Sub PrintDoc_PrintPage(ByVal sender As Object,
|
|
ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDoc.PrintPage
|
|
Dim tmpWidth As Int16, i As Int16
|
|
Dim tmpTop As Int16 = e.MarginBounds.Top
|
|
Dim tmpLeft As Int16 = e.MarginBounds.Left
|
|
Try
|
|
' Before starting first page, it saves Width & Height of Headers and ColumnType
|
|
If PageNo = 1 Then
|
|
For Each GridCol As DataGridViewColumn In dgv.Columns
|
|
If Not GridCol.Visible Then Continue For
|
|
If Not SelectedColumns.Contains(GridCol.HeaderText) Then
|
|
Continue For
|
|
End If
|
|
' Detemining whether the columns are fitted to page or not.
|
|
If FitToPageWidth Then
|
|
tmpWidth = CType(Math.Floor(GridCol.Width / TotalWidth *
|
|
TotalWidth * (e.MarginBounds.Width / TotalWidth)), Int16)
|
|
Else
|
|
tmpWidth = GridCol.Width
|
|
End If
|
|
HeaderHeight = e.Graphics.MeasureString(GridCol.HeaderText,
|
|
drawfont, tmpWidth).Height + 11
|
|
ColumnLefts.Add(tmpLeft)
|
|
ColumnWidths.Add(tmpWidth)
|
|
ColumnTypes.Add(GridCol.GetType)
|
|
tmpLeft += tmpWidth
|
|
Next
|
|
End If
|
|
' Printing Current Page, Row by Row
|
|
Do While RowPos <= dgv.Rows.Count - 1
|
|
Dim GridRow As DataGridViewRow = dgv.Rows(RowPos)
|
|
If GridRow.IsNewRow OrElse (Not PrintAllRows AndAlso Not GridRow.Selected) Then
|
|
RowPos += 1 : Continue Do
|
|
End If
|
|
CellHeight = GridRow.Height ' + 10
|
|
dgv.AutoSizeRowsMode = DataGridViewAutoSizeColumnsMode.AllCells
|
|
'CellHeight = 30
|
|
If tmpTop + CellHeight >= e.MarginBounds.Height + e.MarginBounds.Top Then
|
|
DrawFooter(e, RowsPerPage)
|
|
NewPage = True
|
|
PageNo += 1
|
|
e.HasMorePages = True
|
|
Exit Sub
|
|
Else
|
|
If NewPage Then
|
|
' Draw Header
|
|
e.Graphics.DrawString(PrintTitle, New Font(dgv.Font, FontStyle.Bold),
|
|
Brushes.Black, e.MarginBounds.Left, e.MarginBounds.Top -
|
|
e.Graphics.MeasureString(PrintTitle, New Font(dgv.Font, FontStyle.Bold), e.MarginBounds.Width).Height - 10) ''<-------------------------------------------------------------------13
|
|
Dim s As String = Now.ToLongDateString + " " + Now.ToShortTimeString
|
|
e.Graphics.DrawString(s, New Font(dgv.Font, FontStyle.Bold),
|
|
Brushes.Black, e.MarginBounds.Left + (e.MarginBounds.Width -
|
|
e.Graphics.MeasureString(s, New Font(dgv.Font, FontStyle.Bold),
|
|
e.MarginBounds.Width).Width), e.MarginBounds.Top -
|
|
e.Graphics.MeasureString(PrintTitle,
|
|
New Font(New Font(dgv.Font, FontStyle.Bold), FontStyle.Bold),
|
|
e.MarginBounds.Width).Height - 13)
|
|
' Draw Columns
|
|
tmpTop = e.MarginBounds.Top
|
|
i = 0
|
|
For Each GridCol As DataGridViewColumn In dgv.Columns
|
|
If Not GridCol.Visible Then Continue For
|
|
If Not SelectedColumns.Contains(GridCol.HeaderText) Then
|
|
Continue For
|
|
End If
|
|
' Grey shading for Header Text Box
|
|
e.Graphics.FillRectangle(New SolidBrush(Drawing.Color.LightGray),
|
|
New Rectangle(ColumnLefts(i), tmpTop, ColumnWidths(i), HeaderHeight))
|
|
'Draw Header Text Box
|
|
e.Graphics.DrawRectangle(Pens.Black, New Rectangle(ColumnLefts(i),
|
|
tmpTop, ColumnWidths(i), HeaderHeight))
|
|
'Draw Header Text
|
|
e.Graphics.DrawString(GridCol.HeaderText, GridCol.InheritedStyle.Font,
|
|
New SolidBrush(GridCol.InheritedStyle.ForeColor),
|
|
New RectangleF(ColumnLefts(i), tmpTop, ColumnWidths(i),
|
|
HeaderHeight), StrFormat)
|
|
i += 1
|
|
Next
|
|
NewPage = False
|
|
tmpTop += HeaderHeight
|
|
End If
|
|
i = 0
|
|
For Each Cel As DataGridViewCell In GridRow.Cells
|
|
If Not Cel.OwningColumn.Visible Then Continue For
|
|
If Not SelectedColumns.Contains(Cel.OwningColumn.HeaderText) Then
|
|
Continue For
|
|
End If
|
|
' For the TextBox Column
|
|
If ColumnTypes(i) Is GetType(DataGridViewTextBoxColumn) OrElse
|
|
ColumnTypes(i) Is GetType(DataGridViewLinkColumn) Then
|
|
If Cel.OwningColumn.HeaderText = "A" Or Cel.OwningColumn.HeaderText = "FQDN" Then
|
|
e.Graphics.DrawString(Cel.Value.ToString, drawfont1,
|
|
New SolidBrush(Cel.InheritedStyle.ForeColor),
|
|
New RectangleF(ColumnLefts(i), tmpTop, ColumnWidths(i),
|
|
CellHeight), StrFormat)
|
|
Else
|
|
e.Graphics.DrawString(Cel.Value.ToString, drawfont,
|
|
New SolidBrush(Cel.InheritedStyle.ForeColor),
|
|
New RectangleF(ColumnLefts(i), tmpTop, ColumnWidths(i),
|
|
CellHeight), StrFormat)
|
|
End If
|
|
|
|
' For the Button Column
|
|
ElseIf ColumnTypes(i) Is GetType(DataGridViewButtonColumn) Then
|
|
CellButton.Text = Cel.Value.ToString
|
|
CellButton.Size = New Size(ColumnWidths(i), CellHeight)
|
|
Dim bmp As New Bitmap(CellButton.Width, CellButton.Height)
|
|
CellButton.DrawToBitmap(bmp, New Rectangle(0, 0,
|
|
bmp.Width, bmp.Height))
|
|
e.Graphics.DrawImage(bmp, New Point(ColumnLefts(i), tmpTop))
|
|
' For the CheckBox Column
|
|
ElseIf ColumnTypes(i) Is GetType(DataGridViewCheckBoxColumn) Then
|
|
CellCheckBox.Size = New Size(14, 14)
|
|
CellCheckBox.Checked = CType(Cel.Value, Boolean)
|
|
Dim bmp As New Bitmap(ColumnWidths(i), CellHeight)
|
|
Dim tmpGraphics As Graphics = Graphics.FromImage(bmp)
|
|
tmpGraphics.FillRectangle(Brushes.White, New Rectangle(0, 0,
|
|
bmp.Width, bmp.Height))
|
|
CellCheckBox.DrawToBitmap(bmp, New Rectangle(CType((bmp.Width -
|
|
CellCheckBox.Width) / 2, Int32), CType((bmp.Height -
|
|
CellCheckBox.Height) / 2, Int32), CellCheckBox.Width,
|
|
CellCheckBox.Height))
|
|
e.Graphics.DrawImage(bmp, New Point(ColumnLefts(i), tmpTop))
|
|
' For the ComboBox Column
|
|
ElseIf ColumnTypes(i) Is GetType(DataGridViewComboBoxColumn) Then
|
|
CellComboBox.Size = New Size(ColumnWidths(i), CellHeight)
|
|
Dim bmp As New Bitmap(CellComboBox.Width, CellComboBox.Height)
|
|
CellComboBox.DrawToBitmap(bmp, New Rectangle(0, 0,
|
|
bmp.Width, bmp.Height))
|
|
e.Graphics.DrawImage(bmp, New Point(ColumnLefts(i), tmpTop))
|
|
e.Graphics.DrawString(Cel.Value.ToString, Cel.InheritedStyle.Font,
|
|
New SolidBrush(Cel.InheritedStyle.ForeColor),
|
|
New RectangleF(ColumnLefts(i) + 1, tmpTop, ColumnWidths(i) _
|
|
- 16, CellHeight), StrFormatComboBox)
|
|
' For the Image Column
|
|
ElseIf ColumnTypes(i) Is GetType(DataGridViewImageColumn) Then
|
|
Dim CelSize As Rectangle = New Rectangle(ColumnLefts(i),
|
|
tmpTop, ColumnWidths(i), CellHeight)
|
|
Dim ImgSize As Size = CType(Cel.FormattedValue, Image).Size
|
|
e.Graphics.DrawImage(Cel.FormattedValue, New Rectangle(ColumnLefts(i) _
|
|
+ CType(((CelSize.Width - ImgSize.Width) / 2), Int32),
|
|
tmpTop + CType(((CelSize.Height - ImgSize.Height) / 2),
|
|
Int32), CType(Cel.FormattedValue, Image).Width, CType(Cel.FormattedValue,
|
|
Image).Height))
|
|
End If
|
|
' Drawing Cells Borders
|
|
e.Graphics.DrawRectangle(Pens.Black, New Rectangle(ColumnLefts(i),
|
|
tmpTop, ColumnWidths(i), CellHeight))
|
|
i += 1
|
|
Next
|
|
tmpTop += CellHeight
|
|
End If
|
|
RowPos += 1
|
|
' For the first page it calculates Rows per Page
|
|
If PageNo = 1 Then
|
|
RowsPerPage += 1
|
|
End If
|
|
Loop
|
|
If RowsPerPage = 0 Then Exit Sub
|
|
' Write Footer (Page Number)
|
|
DrawFooter(e, RowsPerPage)
|
|
e.HasMorePages = False
|
|
Catch ex As Exception
|
|
MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
|
|
Finally
|
|
End Try
|
|
End Sub
|
|
Private Shared Sub DrawFooter(ByVal e As System.Drawing.Printing.PrintPageEventArgs, ByVal RowsPerPage As Int32)
|
|
Dim cnt As Integer
|
|
' Detemining rows number to print
|
|
If PrintAllRows Then
|
|
If dgv.Rows(dgv.Rows.Count - 1).IsNewRow Then
|
|
' When the DataGridView doesn't allow adding rows
|
|
cnt = dgv.Rows.Count - 2
|
|
Else
|
|
' When the DataGridView allows adding rows
|
|
cnt = dgv.Rows.Count - 1
|
|
End If
|
|
Else
|
|
cnt = dgv.SelectedRows.Count
|
|
End If
|
|
' Writing the Page Number on the Bottom of Page
|
|
Dim PageNum As String = PageNo.ToString + " of " + Math.Ceiling(cnt / RowsPerPage).ToString
|
|
e.Graphics.DrawString(PageNum, drawfont, Brushes.Black, e.MarginBounds.Left + (e.MarginBounds.Width -
|
|
e.Graphics.MeasureString(PageNum, drawfont, e.MarginBounds.Width).Width) / 2, e.MarginBounds.Top +
|
|
e.MarginBounds.Height + 31)
|
|
End Sub
|
|
End Class
|