|
This is working great. I translated the original into VB.Net but was unable to get it to work. All I got were blank pages. This works.
But... I am having a minor problem. The text in my column headers is a lot longer than what is in the grid cells below. Consequently I'm only getting part of the header text. The remainder is omitted. It is showing all columns, though. Any idea what I may have done wrong or how to correct the issue. Any help will be greatly appreciated.
Thank you.
|
|
|
|
|
how to print DataGridView Data With FitToPage Style
|
|
|
|
|
This is really great! It was easy to read the code and easy to use in my project.
However, I found an issue with the margins. They do not take the printer's hardware margins into account. The 0,0 point of a page is not the corner of the paper but the corner of the printable area. This caused items that have center or far alignment to be too far to the right. To fix this I changed the following in the constructor:
LeftMargin = ThePrintDocument.DefaultPageSettings.Margins.Left;
TopMargin = ThePrintDocument.DefaultPageSettings.Margins.Top;
RightMargin = ThePrintDocument.DefaultPageSettings.Margins.Right;
BottomMargin = ThePrintDocument.DefaultPageSettings.Margins.Bottom;
TO
LeftMargin = ThePrintDocument.DefaultPageSettings.Margins.Left -
(int)ThePrintDocument.DefaultPageSettings.HardMarginX;
TopMargin = ThePrintDocument.DefaultPageSettings.Margins.Top -
(int)ThePrintDocument.DefaultPageSettings.HardMarginY;
RightMargin = ThePrintDocument.DefaultPageSettings.Margins.Right +
(int)ThePrintDocument.DefaultPageSettings.HardMarginX;
BottomMargin = ThePrintDocument.DefaultPageSettings.Margins.Bottom +
(int)ThePrintDocument.DefaultPageSettings.HardMarginY;
-Danny
|
|
|
|
|
Cuando imprimo una grilla con mas columnas de las que caben en una hoja esta funcionalidad imprime las columnas que caben solamente y luego continúa con las filas, una vez recorrida la grilla completa imprime las columnas y filas restantes.
Cómo se puede cambiar para que imprima las columnas que quepan en una hoja y sus filas y luego continúe con las columnas y filas faltantes antes de volver a imprimir la segunda pagina de la grilla, se entiende?
--
When I print a grid with more columns can fit on one sheet printed this feature columns that fit and then just continues with the ranks, once the full print grid columns and rows remaining.
How can be changed to print the columns fit on one sheet and its rows and then continue with the columns and rows missing before you print the second page of the grid, it is understood?
|
|
|
|
|
if i had 100 words in cell, i wanna put it in 2 line, 50 words per line, can i help u?
|
|
|
|
|
Add these two methods to the class:
// Given a row, font and Graphics - calculate the maximum height of the row by checking each of the cells in the row
public Single CalculateMaxRowHeight(int argCurrentRow, Font argFont, StringFormat argCellFormat, Graphics argg)
{
Single RowHeight = 0.0F;
Single CellHeight = 0.0F;
Single CellWidth = 0.0F;
for (int CellNo = (int)mColumnPoints[mColumnPoint].GetValue(0); CellNo < (int)mColumnPoints[mColumnPoint].GetValue(1); CellNo++)
{
if (!TheDataGridView.Columns[CellNo].Visible) continue; // If the cell belongs to invisible column, then ignore this iteration
if (TheDataGridView.Columns[CellNo].DefaultCellStyle.Alignment.ToString().Contains("Right"))
argCellFormat.Alignment = StringAlignment.Far;
else if (TheDataGridView.Columns[CellNo].DefaultCellStyle.Alignment.ToString().Contains("Center"))
argCellFormat.Alignment = StringAlignment.Center;
else
argCellFormat.Alignment = StringAlignment.Near;
CellWidth = ColumnsWidth[CellNo];
CellHeight = CalculateStringHeight(TheDataGridView.Rows[argCurrentRow].Cells[CellNo].EditedFormattedValue.ToString(), argFont, CellWidth, MaxPossibleRowHeight, argCellFormat, argg);
if (CellHeight > RowHeight)
RowHeight = CellHeight;
}
return (RowHeight);
}
// Given the width of a rectangle and a maximum height, calculate the actual height of the rectangle that the text will fit in.
public Single CalculateStringHeight(string argString, Font argFont, Single argWidth, Single argMaxHeight, StringFormat argFormat, Graphics argg)
{
SizeF sf = new SizeF(argWidth, argMaxHeight);
if (argString == "System.Drawing.Bitmap") //If cell contains an image, don't care about height (it is calculated elsewhere)
sf.Height = 0;
else
sf = argg.MeasureString(argString, argFont, sf, argFormat);
return (sf.Height);
}
then inside DrawRows(), around line 380, add:
// Calculate the row height
RowHeight = CalculateMaxRowHeight(CurrentRow, RowFont, CellFormat, g);
|
|
|
|
|
Thanks, thats a big problem... By the way, MaxPossibleRowHeight ???
|
|
|
|
|
Does anyone have the latest code that supports images in the datagridview? I've been trying to add it to the 2006 version but can't seem to get it right...
|
|
|
|
|
It is one of the best and most useful codes that i have ever used.
modified on Friday, May 1, 2009 2:34 AM
|
|
|
|
|
Hi,
For my project I needed to print subtitles, for it I declared the following thing
private Dictionary<string,> cabeceras = new Dictionary<string,>();
public Dictionary<string,> Cabeceras
{
get
{
if (cabeceras == null)
cabeceras = new Dictionary<string,>();
return cabeceras;
}
set { cabeceras = value; }
}
After printing the title I put this
foreach (string sCabeza in Cabeceras.Keys)
{
string strAux = string.Empty;
string strSubCabeza = string.Empty;
strSubCabeza = sCabeza + " - " + ((Cabeceras.TryGetValue(sCabeza, out strAux)) ? strAux : string.Empty);
TitleRectangle = new RectangleF((float)LeftMargin, CurrentY, (float)PageWidth - (float)RightMargin - (float)LeftMargin, g.MeasureString(strSubCabeza, fSubTitulo).Height - 1);
g.DrawString(strSubCabeza, fSubTitulo, new SolidBrush(TheTitleColor), TitleRectangle, TitleFormat);
CurrentY += g.MeasureString(strSubCabeza, fSubTitulo).Height;
}
Finally, when i send to print i put this
Cabeceras.Add("subtitle1","something");
Cabeceras.Add("subtitle2","another thing");
Cabeceras.Add("subtitle3","etc");
I hope that this serves someone.
Regards
|
|
|
|
|
Hello,
How can I extend the DataGridViewPrinter class to support ComboBox and CheckBox columns? Currently the class is printring only the text of such columns. What I want to achieve to is to print a checkbox with check/uncheck mark and comobo box with dropdown arrow.
Regards,
Jehanzeb
|
|
|
|
|
Yes I would really like the same.
Either that (while waiting for the class to present the checkboxes) or do anyone know a quick way to change all the TRUE values to e.g. "X" and all FALSE values to be empty before printing/preview.
something like if(bla bla columnvalues == true) columnvalues = "X"
I've tried but didn't manage to find something that did that.
SOLVED for replacing TRUE with X.
modified on Friday, May 8, 2009 8:51 AM
|
|
|
|
|
If you want something better than True or False for your report, do an if statement or switch statement with the value contained in EditedFormattedValue.ToString().
On the line
<br />
g.DrawString(TheDataGridView.Rows[CurrentRow].Cells[CurrentCell].EditedFormattedValue.ToString(), RowFont, RowForeBrush, CellBounds, CellFormat);<br />
Replace like so
if (TheDataGridView.Rows[CurrentRow].Cells[CurrentCell].EditedFormattedValue.ToString() == "True")<br />
{<br />
<br />
g.DrawString("[X]", RowFont, RowForeBrush, CellBounds, CellFormat);<br />
<br />
}<br />
else if (TheDataGridView.Rows[CurrentRow].Cells[CurrentCell].EditedFormattedValue.ToString() == "False")<br />
{<br />
g.DrawString("[ ]", RowFont, RowForeBrush, CellBounds, CellFormat);<br />
}<br />
else<br />
{<br />
g.DrawString(TheDataGridView.Rows[CurrentRow].Cells[CurrentCell].EditedFormattedValue.ToString(), RowFont, RowForeBrush, CellBounds, CellFormat);<br />
}
|
|
|
|
|
Hi! Great work and very usefull utility! I've integrated the code in my application with good results.
Otherwise I have to advise a little bug: if you build the DataGridViewPrinter object to print the pages without the page numbers, and if the document to print spans in multiple pages, the print job enters in an infinite loop.
The problem is that the "Calculate(Graphics g)" method is called for every page and not just for the first page, beacuse the check
if(pageNumber == 0) { ... }
returns true for all the pages.
Hoping this helps...
Massimo
modified on Monday, November 9, 2009 11:55 AM
|
|
|
|
|
Hello, I Have the same problem.
I declare the object MyPrintDocument this way:
private static PrintDocument _MyPrintDocument;
public static PrintDocument MyPrintDocument
{
get
{
if (_MyPrintDocument == null) {
_MyPrintDocument = new PrintDocument();
_MyPrintDocument.PrintPage += new System.Drawing.Printing.PrintPageEventHandler(MyPrintDocument_PrintPage);}
return _MyPrintDocument;
}
set { _MyPrintDocument = value; }
}
I remove the "if" statement and it work.
|
|
|
|
|
Maybe I don't understand... but the code you posted hasn't mustch to do with the page numbering problem I mentioned. Isn't it?
|
|
|
|
|
Apparently I did not understand you, I am sorry.
My problem was that on having given the orders to print a curl was generated and to be for the form in which I declared the object MyPrintDocument.
I thought that it would be something similar
(Translated with Reverso)
|
|
|
|
|
I've used the Another DataGridView Printer[^] class for about a year now. It works very well, but the author's unorthodox coding style makes it difficult to follow.
This class is much cleaner, and also works well.
From what I can see, though, this class lacks in options, like the ability to include a Subtitle, a Footer, Page Numbering, and numerous minor tweaks that the Another DataGridView Printer[^] class offers.
Both versions lack a variable indicating the total number of pages in the document, and therefore the ability to print only select pages from the document. For a lengthy report, partial page printing would be extremely helpful, especially in this environmentally conscious age.
If I get time to look into this, I hope to fix this problem. For now, though, I'm not offering any solutions.
I hope this review helps others and maybe even sparks some interest in further development.
Thanks to both developers for this tool!
Avoid Sears: http://www.joeswelding.biz/Sears
|
|
|
|
|
|
I have 3 small datagridviews on one form. Rather than print each one to a separate page, wasting paper, I'd like to print them on the same page. Can this class be adapted to do that?
|
|
|
|
|
'corregido el error al imprimir más de una hoja
'no error printing 2 or more pages
'###########################################################
Private Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
'Dim more As Boolean = MyDataGridViewPrinter.DrawDataGridView(e.Graphics)
'If more = True Then
' 'If e.HasMorePages = True Then
' e.HasMorePages = True
' 'End If
'End If
e.HasMorePages = MyDataGridViewPrinter.DrawDataGridView(e.Graphics)
End Sub
'###########################################################
Private Sub cmdImprimir_Click(ByVal eventSender As System.Object, ByVal eventArgs As System.EventArgs) Handles cmdImprimir.Click
Dim MyPrintDialog As New PrintDialog()
Dim Centrado As Boolean = True
Dim TieneTitulo As Boolean = True
Dim NumeroPagina As Boolean = False
Dim Titulo As String = "Informacion Mayores Volumenes"
Dim Fuente As New Font("Tahoma", 12, FontStyle.Bold, GraphicsUnit.Point)
Dim ColorTitulo As Color = Color.Black
Dim Margenes As New Margins(20, 20, 20, 20)
MyPrintDialog.AllowCurrentPage = False
MyPrintDialog.AllowPrintToFile = False
MyPrintDialog.AllowSelection = False
MyPrintDialog.AllowSomePages = False
MyPrintDialog.PrintToFile = False
MyPrintDialog.ShowHelp = False
MyPrintDialog.ShowNetwork = False
If MyPrintDialog.ShowDialog() <> DialogResult.OK Then Exit Sub
PrintDocument1.DocumentName = Titulo
PrintDocument1.PrinterSettings = MyPrintDialog.PrinterSettings
PrintDocument1.DefaultPageSettings = MyPrintDialog.PrinterSettings.DefaultPageSettings
PrintDocument1.DefaultPageSettings.Margins = Margenes
MyDataGridViewPrinter = New DataGridViewPrinter(grdInformacionMiembroValor, PrintDocument1, Centrado, TieneTitulo, Titulo, Fuente, ColorTitulo, NumeroPagina)
Dim MyPrintPreviewDialog As New PrintPreviewDialog()
MyPrintPreviewDialog.Document = PrintDocument1
MyPrintPreviewDialog.ShowDialog()
'PrintDocument1.Print()
End Sub
'###########################################################
Imports System.Collections.Generic
Imports System.Drawing.Printing
Public Class DataGridViewprinter
Private TheDataGridView As DataGridView
' The DataGridView Control which will be printed
Private ThePrintDocument As PrintDocument
' The PrintDocument to be used for printing
Private IsCenterOnPage As Boolean
' Determine if the report will be printed in the Top-Center of the page
Private IsWithTitle As Boolean
' Determine if the page contain title text
Private TheTitleText As String
' The title text to be printed in each page (if IsWithTitle is set to true)
Private TheTitleFont As Font
' The font to be used with the title text (if IsWithTitle is set to true)
Private TheTitleColor As Color
' The color to be used with the title text (if IsWithTitle is set to true)
Private IsWithPaging As Boolean
' Determine if paging is used
Dim CurrentRow As Integer
' A static parameter that keep track on which Row (in the DataGridView control) that should be printed
Dim PageNumber As Integer
Private PageWidth As Integer
Private PageHeight As Integer
Private LeftMargin As Integer
Private TopMargin As Integer
Private RightMargin As Integer
Private BottomMargin As Integer
Private CurrentY As Single
' A parameter that keep track on the y coordinate of the page, so the next object to be printed will start from this y coordinate
Private RowHeaderHeight As Single
Private RowsHeight As List(Of Single)
Private ColumnsWidth As List(Of Single)
Private TheDataGridViewWidth As Single
' Maintain a generic list to hold start/stop points for the column printing
' This will be used for wrapping in situations where the DataGridView will not fit on a single page
Private mColumnPoints As List(Of Integer())
Private mColumnPointsWidth As List(Of Single)
Private mColumnPoint As Integer
Private DejaFait As Boolean
' The class constructor
Public Sub New(ByVal aDataGridView As DataGridView, ByVal aPrintDocument As PrintDocument, ByVal CenterOnPage As Boolean, ByVal WithTitle As Boolean, ByVal aTitleText As String, ByVal aTitleFont As Font, _
ByVal aTitleColor As Color, ByVal WithPaging As Boolean)
TheDataGridView = aDataGridView
ThePrintDocument = aPrintDocument
IsCenterOnPage = CenterOnPage
IsWithTitle = WithTitle
TheTitleText = aTitleText
TheTitleFont = aTitleFont
TheTitleColor = aTitleColor
IsWithPaging = WithPaging
PageNumber = 0
RowsHeight = New List(Of Single)()
ColumnsWidth = New List(Of Single)()
mColumnPoints = New List(Of Integer())()
mColumnPointsWidth = New List(Of Single)()
' Claculating the PageWidth and the PageHeight
If Not ThePrintDocument.DefaultPageSettings.Landscape Then
PageWidth = ThePrintDocument.DefaultPageSettings.PaperSize.Width
PageHeight = ThePrintDocument.DefaultPageSettings.PaperSize.Height
Else
PageHeight = ThePrintDocument.DefaultPageSettings.PaperSize.Width
PageWidth = ThePrintDocument.DefaultPageSettings.PaperSize.Height
End If
' Claculating the page margins
LeftMargin = ThePrintDocument.DefaultPageSettings.Margins.Left
TopMargin = ThePrintDocument.DefaultPageSettings.Margins.Top
RightMargin = ThePrintDocument.DefaultPageSettings.Margins.Right
BottomMargin = ThePrintDocument.DefaultPageSettings.Margins.Bottom
' First, the current row to be printed is the first row in the DataGridView control
CurrentRow = 0
End Sub
' The function that calculate the height of each row (including the header row), the width of each column (according to the longest text in all its cells including the header cell), and the whole DataGridView width
Private Sub Calculate(ByVal g As Graphics)
'if (PageNumber == 0) // Just calculate once
If (PageNumber = 0) AndAlso (DejaFait = False) Then
' Just calculate once
'DejaFait = true
Dim tmpSize As New SizeF()
Dim tmpFont As Font
Dim tmpWidth As Single
TheDataGridViewWidth = 0
For i As Integer = 0 To TheDataGridView.Columns.Count - 1
tmpFont = TheDataGridView.ColumnHeadersDefaultCellStyle.Font
If tmpFont Is Nothing Then
' If there is no special HeaderFont style, then use the default DataGridView font style
tmpFont = TheDataGridView.DefaultCellStyle.Font
End If
tmpSize = g.MeasureString(TheDataGridView.Columns(i).HeaderText, tmpFont)
tmpWidth = tmpSize.Width
RowHeaderHeight = tmpSize.Height
For j As Integer = 0 To TheDataGridView.Rows.Count - 1
tmpFont = TheDataGridView.Rows(j).DefaultCellStyle.Font
If tmpFont Is Nothing Then
' If the there is no special font style of the CurrentRow, then use the default one associated with the DataGridView control
tmpFont = TheDataGridView.DefaultCellStyle.Font
End If
tmpSize = g.MeasureString("Anything", tmpFont)
RowsHeight.Add(tmpSize.Height)
tmpSize = g.MeasureString(TheDataGridView.Rows(j).Cells(i).EditedFormattedValue.ToString(), tmpFont)
If tmpSize.Width > tmpWidth Then
tmpWidth = tmpSize.Width
End If
Next
If TheDataGridView.Columns(i).Visible Then
TheDataGridViewWidth += tmpWidth
End If
ColumnsWidth.Add(tmpWidth)
Next
' Define the start/stop column points based on the page width and the DataGridView Width
' We will use this to determine the columns which are drawn on each page and how wrapping will be handled
' By default, the wrapping will occurr such that the maximum number of columns for a page will be determine
Dim k As Integer
Dim mStartPoint As Integer = 0
For k = 0 To TheDataGridView.Columns.Count - 1
If TheDataGridView.Columns(k).Visible Then
mStartPoint = k
Exit For
End If
Next
Dim mEndPoint As Integer = TheDataGridView.Columns.Count
For k = TheDataGridView.Columns.Count - 1 To 0 Step -1
If TheDataGridView.Columns(k).Visible Then
mEndPoint = k + 1
Exit For
End If
Next
Dim mTempWidth As Single = TheDataGridViewWidth
Dim mTempPrintArea As Single = CSng(PageWidth) - CSng(LeftMargin) - CSng(RightMargin)
' We only care about handling where the total datagridview width is bigger then the print area
If TheDataGridViewWidth > mTempPrintArea Then
mTempWidth = 0.0F
For k = 0 To TheDataGridView.Columns.Count - 1
If TheDataGridView.Columns(k).Visible Then
mTempWidth += ColumnsWidth(k)
' If the width is bigger than the page area, then define a new column print range
If mTempWidth > mTempPrintArea Then
mTempWidth -= ColumnsWidth(k)
mColumnPoints.Add(New Integer() {mStartPoint, mEndPoint})
mColumnPointsWidth.Add(mTempWidth)
mStartPoint = k
mTempWidth = ColumnsWidth(k)
End If
End If
' Our end point is actually one index above the current index
mEndPoint = k + 1
Next
End If
' Add the last set of columns
mColumnPoints.Add(New Integer() {mStartPoint, mEndPoint})
mColumnPointsWidth.Add(mTempWidth)
'mColumnPoint = 0
End If
End Sub
' The funtion that print the title, page number, and the header row
Private Sub DrawHeader(ByVal g As Graphics)
CurrentY = CSng(TopMargin)
' Printing the page number (if isWithPaging is set to true)
If IsWithPaging Then
PageNumber += 1
Dim PageString As String = "Page " & PageNumber.ToString()
Dim PageStringFormat As New StringFormat()
PageStringFormat.Trimming = StringTrimming.Word
PageStringFormat.FormatFlags = StringFormatFlags.NoWrap Or StringFormatFlags.LineLimit Or StringFormatFlags.NoClip
PageStringFormat.Alignment = StringAlignment.Far
Dim PageStringFont As New Font("Tahoma", 8, FontStyle.Regular, GraphicsUnit.Point)
Dim PageStringRectangle As New RectangleF(CSng(LeftMargin), CurrentY, CSng(PageWidth) - CSng(RightMargin) - CSng(LeftMargin), g.MeasureString(PageString, PageStringFont).Height)
g.DrawString(PageString, PageStringFont, New SolidBrush(Color.Black), PageStringRectangle, PageStringFormat)
CurrentY += g.MeasureString(PageString, PageStringFont).Height
End If
' Printing the title (if IsWithTitle is set to true)
If IsWithTitle Then
Dim TitleFormat As New StringFormat()
TitleFormat.Trimming = StringTrimming.Word
TitleFormat.FormatFlags = StringFormatFlags.NoWrap Or StringFormatFlags.LineLimit Or StringFormatFlags.NoClip
If IsCenterOnPage Then
TitleFormat.Alignment = StringAlignment.Center
Else
TitleFormat.Alignment = StringAlignment.Near
End If
Dim TitleRectangle As New RectangleF(CSng(LeftMargin), CurrentY, CSng(PageWidth) - CSng(RightMargin) - CSng(LeftMargin), g.MeasureString(TheTitleText, TheTitleFont).Height)
g.DrawString(TheTitleText, TheTitleFont, New SolidBrush(TheTitleColor), TitleRectangle, TitleFormat)
CurrentY += g.MeasureString(TheTitleText, TheTitleFont).Height
End If
' Calculating the starting x coordinate that the printing process will start from
Dim CurrentX As Single = CSng(LeftMargin)
If IsCenterOnPage Then
CurrentX += ((CSng(PageWidth) - CSng(RightMargin) - CSng(LeftMargin)) - mColumnPointsWidth(mColumnPoint)) / 2.0F
End If
' Setting the HeaderFore style
Dim HeaderForeColor As Color = TheDataGridView.ColumnHeadersDefaultCellStyle.ForeColor
If HeaderForeColor.IsEmpty Then
' If there is no special HeaderFore style, then use the default DataGridView style
HeaderForeColor = TheDataGridView.DefaultCellStyle.ForeColor
End If
Dim HeaderForeBrush As New SolidBrush(HeaderForeColor)
' Setting the HeaderBack style
Dim HeaderBackColor As Color = TheDataGridView.ColumnHeadersDefaultCellStyle.BackColor
If HeaderBackColor.IsEmpty Then
' If there is no special HeaderBack style, then use the default DataGridView style
HeaderBackColor = TheDataGridView.DefaultCellStyle.BackColor
End If
Dim HeaderBackBrush As New SolidBrush(HeaderBackColor)
' Setting the LinePen that will be used to draw lines and rectangles (derived from the GridColor property of the DataGridView control)
Dim TheLinePen As New Pen(TheDataGridView.GridColor, 1)
' Setting the HeaderFont style
Dim HeaderFont As Font = TheDataGridView.ColumnHeadersDefaultCellStyle.Font
If HeaderFont Is Nothing Then
' If there is no special HeaderFont style, then use the default DataGridView font style
HeaderFont = TheDataGridView.DefaultCellStyle.Font
End If
' Calculating and drawing the HeaderBounds
Dim HeaderBounds As New RectangleF(CurrentX, CurrentY, mColumnPointsWidth(mColumnPoint), RowHeaderHeight)
g.FillRectangle(HeaderBackBrush, HeaderBounds)
' Setting the format that will be used to print each cell of the header row
Dim CellFormat As New StringFormat()
CellFormat.Trimming = StringTrimming.Word
CellFormat.FormatFlags = StringFormatFlags.NoWrap Or StringFormatFlags.LineLimit Or StringFormatFlags.NoClip
' Printing each visible cell of the header row
Dim CellBounds As RectangleF
Dim ColumnWidth As Single
For i As Integer = CInt(mColumnPoints(mColumnPoint).GetValue(0)) To CInt(mColumnPoints(mColumnPoint).GetValue(1)) - 1
If Not TheDataGridView.Columns(i).Visible Then
Continue For
End If
' If the column is not visible then ignore this iteration
ColumnWidth = ColumnsWidth(i)
' Check the CurrentCell alignment and apply it to the CellFormat
If TheDataGridView.ColumnHeadersDefaultCellStyle.Alignment.ToString().Contains("Right") Then
CellFormat.Alignment = StringAlignment.Far
ElseIf TheDataGridView.ColumnHeadersDefaultCellStyle.Alignment.ToString().Contains("Center") Then
CellFormat.Alignment = StringAlignment.Center
Else
CellFormat.Alignment = StringAlignment.Near
End If
CellBounds = New RectangleF(CurrentX, CurrentY, ColumnWidth, RowHeaderHeight)
' Printing the cell text
g.DrawString(TheDataGridView.Columns(i).HeaderText, HeaderFont, HeaderForeBrush, CellBounds, CellFormat)
' Drawing the cell bounds
If TheDataGridView.RowHeadersBorderStyle <> DataGridViewHeaderBorderStyle.None Then
' Draw the cell border only if the HeaderBorderStyle is not None
g.DrawRectangle(TheLinePen, CurrentX, CurrentY, ColumnWidth, RowHeaderHeight)
End If
CurrentX += ColumnWidth
Next
CurrentY += RowHeaderHeight
End Sub
' The function that print a bunch of rows that fit in one page
' When it returns true, meaning that there are more rows still not printed, so another PagePrint action is required
' When it returns false, meaning that all rows are printed (the CureentRow parameter reaches the last row of the DataGridView control) and no further PagePrint action is required
Private Function DrawRows(ByVal g As Graphics) As Boolean
' Setting the LinePen that will be used to draw lines and rectangles (derived from the GridColor property of the DataGridView control)
Dim TheLinePen As New Pen(TheDataGridView.GridColor, 1)
' The style paramters that will be used to print each cell
Dim RowFont As Font
Dim RowForeColor As Color
Dim RowBackColor As Color
Dim RowForeBrush As SolidBrush
Dim RowBackBrush As SolidBrush
Dim RowAlternatingBackBrush As SolidBrush
' Setting the format that will be used to print each cell
Dim CellFormat As New StringFormat()
CellFormat.Trimming = StringTrimming.Word
CellFormat.FormatFlags = StringFormatFlags.NoWrap Or StringFormatFlags.LineLimit
' Printing each visible cell
Dim RowBounds As RectangleF
Dim CurrentX As Single
Dim ColumnWidth As Single
While CurrentRow < TheDataGridView.Rows.Count
If TheDataGridView.Rows(CurrentRow).Visible Then
' Print the cells of the CurrentRow only if that row is visible
' Setting the row font style
RowFont = TheDataGridView.Rows(CurrentRow).DefaultCellStyle.Font
If RowFont Is Nothing Then
' If the there is no special font style of the CurrentRow, then use the default one associated with the DataGridView control
RowFont = TheDataGridView.DefaultCellStyle.Font
End If
' Setting the RowFore style
RowForeColor = TheDataGridView.Rows(CurrentRow).DefaultCellStyle.ForeColor
If RowForeColor.IsEmpty Then
' If the there is no special RowFore style of the CurrentRow, then use the default one associated with the DataGridView control
RowForeColor = TheDataGridView.DefaultCellStyle.ForeColor
End If
RowForeBrush = New SolidBrush(RowForeColor)
' Setting the RowBack (for even rows) and the RowAlternatingBack (for odd rows) styles
RowBackColor = TheDataGridView.Rows(CurrentRow).DefaultCellStyle.BackColor
If RowBackColor.IsEmpty Then
' If the there is no special RowBack style of the CurrentRow, then use the default one associated with the DataGridView control
RowBackBrush = New SolidBrush(TheDataGridView.DefaultCellStyle.BackColor)
RowAlternatingBackBrush = New SolidBrush(TheDataGridView.AlternatingRowsDefaultCellStyle.BackColor)
Else
' If the there is a special RowBack style of the CurrentRow, then use it for both the RowBack and the RowAlternatingBack styles
RowBackBrush = New SolidBrush(RowBackColor)
RowAlternatingBackBrush = New SolidBrush(RowBackColor)
End If
' Calculating the starting x coordinate that the printing process will start from
CurrentX = CSng(LeftMargin)
If IsCenterOnPage Then
CurrentX += ((CSng(PageWidth) - CSng(RightMargin) - CSng(LeftMargin)) - mColumnPointsWidth(mColumnPoint)) / 2.0F
End If
' Calculating the entire CurrentRow bounds
RowBounds = New RectangleF(CurrentX, CurrentY, mColumnPointsWidth(mColumnPoint), RowsHeight(CurrentRow))
' Filling the back of the CurrentRow
If CurrentRow Mod 2 = 0 Then
g.FillRectangle(RowBackBrush, RowBounds)
Else
g.FillRectangle(RowAlternatingBackBrush, RowBounds)
End If
' Printing each visible cell of the CurrentRow
For CurrentCell As Integer = CInt(mColumnPoints(mColumnPoint).GetValue(0)) To CInt(mColumnPoints(mColumnPoint).GetValue(1)) - 1
If Not TheDataGridView.Columns(CurrentCell).Visible Then
Continue For
End If
' If the cell is belong to invisible column, then ignore this iteration
' Check the CurrentCell alignment and apply it to the CellFormat
If TheDataGridView.Columns(CurrentCell).DefaultCellStyle.Alignment.ToString().Contains("Right") Then
CellFormat.Alignment = StringAlignment.Far
ElseIf TheDataGridView.Columns(CurrentCell).DefaultCellStyle.Alignment.ToString().Contains("Center") Then
CellFormat.Alignment = StringAlignment.Center
Else
CellFormat.Alignment = StringAlignment.Near
End If
ColumnWidth = ColumnsWidth(CurrentCell)
Dim CellBounds As New RectangleF(CurrentX, CurrentY, ColumnWidth, RowsHeight(CurrentRow))
' Printing the cell text
g.DrawString(TheDataGridView.Rows(CurrentRow).Cells(CurrentCell).EditedFormattedValue.ToString(), RowFont, RowForeBrush, CellBounds, CellFormat)
' Drawing the cell bounds
If TheDataGridView.CellBorderStyle <> DataGridViewCellBorderStyle.None Then
' Draw the cell border only if the CellBorderStyle is not None
g.DrawRectangle(TheLinePen, CurrentX, CurrentY, ColumnWidth, RowsHeight(CurrentRow))
End If
CurrentX += ColumnWidth
Next
CurrentY += RowsHeight(CurrentRow)
' Checking if the CurrentY is exceeds the page boundries
' If so then exit the function and returning true meaning another PagePrint action is required
If CInt(CurrentY) > (PageHeight - TopMargin - BottomMargin) Then
CurrentRow += 1
Return True
End If
End If
CurrentRow += 1
End While
CurrentRow = 0
'mColumnPoint += 1
' Continue to print the next group of columns
'If mColumnPoint = mColumnPoints.Count Then
' Which means all columns are printed
mColumnPoint = 0
Return False
'Else
'Return True
'End If
End Function
' The method that calls all other functions
Public Function DrawDataGridView(ByVal g As Graphics) As Boolean
Try
Calculate(g)
DrawHeader(g)
Dim bContinue As Boolean = DrawRows(g)
'================================
If bContinue = False Then
PageNumber = 0
DejaFait = True
End If
'================================
Return bContinue
Catch ex As Exception
MessageBox.Show("Operation failed: " & ex.Message.ToString(), Application.ProductName & " - Error", MessageBoxButtons.OK, MessageBoxIcon.[Error])
Return False
End Try
End Function
End Class
modified on Thursday, March 12, 2009 3:40 PM
|
|
|
|
|
thanks a lot! great code! works very well.
|
|
|
|
|
Thank you! its very good...
|
|
|
|
|
Dear Salan
Can you post a working project of DataGridPrinter Class in VB.NET so we can download and test it?
Thanks
|
|
|
|
|
Hi, thank you very for this class, it works wonders.
However, I am just wondering how I would manage to get the Vertical allignemnt (because I modified the height of the cell) within the cell to be at Center as it is in my dataGridView.
Also, when I go into the preview print window and press print from within there the printouts do not stop coming, it just keeps on printing, any ideas on how I would fix this?
Thank you
A Trujillo
|
|
|
|
|