|
Hi, I'd like to print only certain columns of a DataGridView. How would something like this be done? I couldn't find any code examples. Thanks | | Daikoku Friday, July 08, 2005 4:01 PM | There isn't any built in printing support, so there are two options: 1) Use the standard printing system provided by Windows Forms and manually print out the information that you want. Check out the documentation for PrintPage and PrintDocument
2) Use the DataGridView's clipboard copy support to copy the content to an Excel file and then print that.
Hope this helps, -mark DataGridView Program Manager Microsoft This post is provided "as-is" | | Mark Rideout Friday, July 08, 2005 5:51 PM | Wow, I haven't see that, unless you are using TextRenderer.DrawText for your printing. Unfortunitely TextRenderer.DrawText uses GDI while Graphics.DrawString uses GDI+. GDI drawing with our current print engine doesn't work correctly, so you'll need to use Graphics.DrawString.
Let me know if that works. If that isn't the case then can you file a bug and we'll investigate it? Thanks
-mark DataGridView Program Manager Microsoft This post is provided "as-is" | | Mark Rideout Monday, July 11, 2005 7:26 PM | There isn't any built in printing support, so there are two options: 1) Use the standard printing system provided by Windows Forms and manually print out the information that you want. Check out the documentation for PrintPage and PrintDocument
2) Use the DataGridView's clipboard copy support to copy the content to an Excel file and then print that.
Hope this helps, -mark DataGridView Program Manager Microsoft This post is provided "as-is" | | Mark Rideout Friday, July 08, 2005 5:51 PM | ok, I just wrote a class that works with PrintPage and PrintDocument and everything looks good in the print preview dialog. However, as soon as I'm printing, only the grid headers and some extra text I added (page numbers, etc.) are printed. None of the DataGridView content that I painted and is visible in the print preview is printed to the output document. Any idea why this could be the case? | | Daikoku Monday, July 11, 2005 1:54 PM | Wow, I haven't see that, unless you are using TextRenderer.DrawText for your printing. Unfortunitely TextRenderer.DrawText uses GDI while Graphics.DrawString uses GDI+. GDI drawing with our current print engine doesn't work correctly, so you'll need to use Graphics.DrawString.
Let me know if that works. If that isn't the case then can you file a bug and we'll investigate it? Thanks
-mark DataGridView Program Manager Microsoft This post is provided "as-is" | | Mark Rideout Monday, July 11, 2005 7:26 PM | I'm using DrawString... here's my code ... it's a bit messy right now but should do the job ;) | | private void printDocument_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e) { int x = 0; int y = 100; int rowGap = 20; int colGap = 5; int leftMargin = 50; int linesPerPage = e.MarginBounds.Height / _dataGridView.DefaultCellStyle.Font.Height; Font font = new Font(_dataGridView.DefaultCellStyle.Font.FontFamily, _dataGridView.DefaultCellStyle.Font.Size); Font headingFont = new Font("Arial", 10, FontStyle.Bold); Font captionFont = new Font("Arial", 10, FontStyle.Bold); Brush brush = new SolidBrush(Color.Black); string cellValue = ""; e.Graphics.DrawString("Erstellt von " + ObjectStore.Account.UserName + " am " + DateTime.Now.ToLongDateString(), captionFont, brush, new PointF(50, 50)); e.Graphics.DrawString("Seite " + _pageNumber, captionFont, brush, new PointF(e.PageBounds.Width - 100, e.PageBounds.Height - 50)); int rowCount = _dataGridView.Rows.Count; int colCount = _dataGridView.Columns.Count; y += rowGap; x = leftMargin; foreach (DataGridViewColumn column in _dataGridView.Columns) { if(column.GetType() != typeof(DataGridViewButtonColumn) && column.GetType() != typeof(DataGridViewCheckBoxColumn)) { cellValue = column.HeaderText; e.Graphics.DrawString(cellValue, headingFont, brush, x, y); x += column.Width + colGap; } } int count = 0; for (int i = _rowPosition; i < _dataGridView.Rows.Count; i++) { y += rowGap; x = leftMargin; foreach (DataGridViewColumn column in _dataGridView.Columns) { if (column.GetType() != typeof(DataGridViewButtonColumn) && column.GetType() != typeof(DataGridViewCheckBoxColumn)) { cellValue = _dataGridView.Rows //emoticons/emotion-55.gif" alt="Idea" />.Cells[column.Index].Value.ToString(); e.Graphics.DrawString(cellValue, captionFont, brush, x, y); x += column.Width + colGap; y = y + rowGap * (cellValue.Split(new char[] { '\r', '\n' }).Length - 1); } } _rowPosition++; count++; if (count > linesPerPage) { break; } } if (_rowPosition > linesPerPage && _rowPosition < _dataGridView.Rows.Count) { _pageNumber++; e.HasMorePages = true; } } | | | Daikoku Monday, July 11, 2005 10:07 PM | any takers? ;) | | Daikoku Wednesday, July 13, 2005 12:16 PM | The MSDN library provides the following guidance for printing a DataGrid... This example demonstrates printing a DataGrid control. Exampleprivate void printGrid_Click(System.Object sender, System.EventArgs e) { printDocument1.Print(); } private void printDocument1_PrintPage(System.Object sender, System.Drawing.Printing.PrintPageEventArgs e) { PaintEventArgs myPaintArgs = new PaintEventArgs(e.Graphics, new Rectangle(new Point(0, 0), this.Size)); this.InvokePaint(dataGrid1, myPaintArgs);
Is it planned to have this work for the DataGridView? I have tried to use it but it printed only the Grid, omitting the contents of the cells. Does the code in the above example work in VS 2005? That is, maybe I should copy the contents of my DataGridView to a DataGrid and print from there!
| | GraemeWT Wednesday, August 17, 2005 1:59 AM | For anyone needing to know how to start printing a grid, here is some code I whipped up after not finding any samples I could heist from someone else. I'm sure there are better ways to do this, but like I said, this is a start. Probably why MS doesn't offer a print function or component is because there is truly an unlimited number of configurations for a print setup. To achieve most of them isn't even rocket science, the beauty of VB.NET. Cheers.
Private oStringFormat As StringFormat Private oStringFormatComboBox As StringFormat Private oButton As Button Private oCheckbox As CheckBox Private oComboBox As ComboBox
Private nTotalWidth As Int16 Private nRowPos As Int16 Private NewPage As Boolean Private nPageNo As Int16 Private Header As String = "Header Test" Private sUserName As String = "Will"
Private Sub PrintDocument1_BeginPrint(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintEventArgs) Handles PrintDocument1.BeginPrint
oStringFormat = New StringFormat oStringFormat.Alignment = StringAlignment.Near oStringFormat.LineAlignment = StringAlignment.Center oStringFormat.Trimming = StringTrimming.EllipsisCharacter
oStringFormatComboBox = New StringFormat oStringFormatComboBox.LineAlignment = StringAlignment.Center oStringFormatComboBox.FormatFlags = StringFormatFlags.NoWrap oStringFormatComboBox.Trimming = StringTrimming.EllipsisCharacter
oButton = New Button oCheckbox = New CheckBox oComboBox = New ComboBox
nTotalWidth = 0 For Each oColumn As DataGridViewColumn In DataGridView1.Columns
nTotalWidth += oColumn.Width
Next nPageNo = 1 NewPage = True nRowPos = 0
End Sub
Private Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
Static oColumnLefts As New ArrayList Static oColumnWidths As New ArrayList Static oColumnTypes As New ArrayList Static nHeight As Int16
Dim nWidth, i, nRowsPerPage As Int16 Dim nTop As Int16 = e.MarginBounds.Top Dim nLeft As Int16 = e.MarginBounds.Left
If nPageNo = 1 Then
For Each oColumn As DataGridViewColumn In DataGridView1.Columns
nWidth = CType(Math.Floor(oColumn.Width / nTotalWidth * nTotalWidth * (e.MarginBounds.Width / nTotalWidth)), Int16)
nHeight = e.Graphics.MeasureString(oColumn.HeaderText, oColumn.InheritedStyle.Font, nWidth).Height + 11
oColumnLefts.Add(nLeft) oColumnWidths.Add(nWidth) oColumnTypes.add(oColumn.GetType) nLeft += nWidth
Next
End If
Do While nRowPos < DataGridView1.Rows.Count - 1
Dim oRow As DataGridViewRow = DataGridView1.Rows(nRowPos)
If nTop + nHeight >= e.MarginBounds.Height + e.MarginBounds.Top Then
DrawFooter(e, nRowsPerPage)
NewPage = True nPageNo += 1 e.HasMorePages = True Exit Sub
Else
If NewPage Then
' Draw Header e.Graphics.DrawString(Header, New Font(DataGridView1.Font, FontStyle.Bold), Brushes.Black, e.MarginBounds.Left, e.MarginBounds.Top - e.Graphics.MeasureString(Header, New Font(DataGridView1.Font, FontStyle.Bold), e.MarginBounds.Width).Height - 13)
' Draw Columns nTop = e.MarginBounds.Top i = 0 For Each oColumn As DataGridViewColumn In DataGridView1.Columns
e.Graphics.FillRectangle(New SolidBrush(Drawing.Color.LightGray), New Rectangle(oColumnLefts(i), nTop, oColumnWidths(i), nHeight)) e.Graphics.DrawRectangle(Pens.Black, New Rectangle(oColumnLefts(i), nTop, oColumnWidths(i), nHeight)) e.Graphics.DrawString(oColumn.HeaderText, oColumn.InheritedStyle.Font, New SolidBrush(oColumn.InheritedStyle.ForeColor), New RectangleF(oColumnLefts(i), nTop, oColumnWidths(i), nHeight), oStringFormat) i += 1
Next NewPage = False
End If
nTop += nHeight i = 0 For Each oCell As DataGridViewCell In oRow.Cells
If oColumnTypes(i) Is GetType(DataGridViewTextBoxColumn) OrElse oColumnTypes(i) Is GetType(DataGridViewLinkColumn) Then
e.Graphics.DrawString(oCell.Value.ToString, oCell.InheritedStyle.Font, New SolidBrush(oCell.InheritedStyle.ForeColor), New RectangleF(oColumnLefts(i), nTop, oColumnWidths(i), nHeight), oStringFormat)
ElseIf oColumnTypes(i) Is GetType(DataGridViewButtonColumn) Then
oButton.Text = oCell.Value.ToString oButton.Size = New Size(oColumnWidths(i), nHeight) Dim oBitmap As New Bitmap(oButton.Width, oButton.Height) oButton.DrawToBitmap(oBitmap, New Rectangle(0, 0, oBitmap.Width, oBitmap.Height)) e.Graphics.DrawImage(oBitmap, New Point(oColumnLefts(i), nTop))
ElseIf oColumnTypes(i) Is GetType(DataGridViewCheckBoxColumn) Then
oCheckbox.Size = New Size(14, 14) oCheckbox.Checked = CType(oCell.Value, Boolean) Dim oBitmap As New Bitmap(oColumnWidths(i), nHeight) Dim oTempGraphics As Graphics = Graphics.FromImage(oBitmap) oTempGraphics.FillRectangle(Brushes.White, New Rectangle(0, 0, oBitmap.Width, oBitmap.Height)) oCheckbox.DrawToBitmap(oBitmap, New Rectangle(CType((oBitmap.Width - oCheckbox.Width) / 2, Int32), CType((oBitmap.Height - oCheckbox.Height) / 2, Int32), oCheckbox.Width, oCheckbox.Height)) e.Graphics.DrawImage(oBitmap, New Point(oColumnLefts(i), nTop))
ElseIf oColumnTypes(i) Is GetType(DataGridViewComboBoxColumn) Then
oComboBox.Size = New Size(oColumnWidths(i), nHeight) Dim oBitmap As New Bitmap(oComboBox.Width, oComboBox.Height) oComboBox.DrawToBitmap(oBitmap, New Rectangle(0, 0, oBitmap.Width, oBitmap.Height)) e.Graphics.DrawImage(oBitmap, New Point(oColumnLefts(i), nTop)) e.Graphics.DrawString(oCell.Value.ToString, oCell.InheritedStyle.Font, New SolidBrush(oCell.InheritedStyle.ForeColor), New RectangleF(oColumnLefts(i) + 1, nTop, oColumnWidths(i) - 16, nHeight), oStringFormatComboBox)
ElseIf oColumnTypes(i) Is GetType(DataGridViewImageColumn) Then
Dim oCellSize As Rectangle = New Rectangle(oColumnLefts(i), nTop, oColumnWidths(i), nHeight) Dim oImageSize As Size = CType(oCell.Value, Image).Size e.Graphics.DrawImage(oCell.Value, New Rectangle(oColumnLefts(i) + CType(((oCellSize.Width - oImageSize.Width) / 2), Int32), nTop + CType(((oCellSize.Height - oImageSize.Height) / 2), Int32), CType(oCell.Value, Image).Width, CType(oCell.Value, Image).Height))
End If
e.Graphics.DrawRectangle(Pens.Black, New Rectangle(oColumnLefts(i), nTop, oColumnWidths(i), nHeight))
i += 1
Next
End If
nRowPos += 1 nRowsPerPage += 1
Loop
DrawFooter(e, nRowsPerPage)
e.HasMorePages = False
End Sub
Private Sub DrawFooter(ByVal e As System.Drawing.Printing.PrintPageEventArgs, ByVal RowsPerPage As Int32)
Dim sPageNo As String = nPageNo.ToString + " of " + Math.Ceiling(DataGridView1.Rows.Count / RowsPerPage).ToString
' Right Align - User Name e.Graphics.DrawString(sUserName, DataGridView1.Font, Brushes.Black, e.MarginBounds.Left + (e.MarginBounds.Width - e.Graphics.MeasureString(sPageNo, DataGridView1.Font, e.MarginBounds.Width).Width), e.MarginBounds.Top + e.MarginBounds.Height + 7)
' Left Align - Date/Time e.Graphics.DrawString(Now.ToLongDateString + " " + Now.ToShortTimeString, DataGridView1.Font, Brushes.Black, e.MarginBounds.Left, e.MarginBounds.Top + e.MarginBounds.Height + 7)
' Center - Page No. Info e.Graphics.DrawString(sPageNo, DataGridView1.Font, Brushes.Black, e.MarginBounds.Left + (e.MarginBounds.Width - e.Graphics.MeasureString(sPageNo, DataGridView1.Font, e.MarginBounds.Width).Width) / 2, e.MarginBounds.Top + e.MarginBounds.Height + 31)
End Sub | | will_affinity Saturday, January 07, 2006 6:54 PM | Will,
This is great code. Thank you!!! This works great for a straight print. I've played around with the code but can't seem to get it to work with print preview or a printdialog control. Do you have any code or have any idea on how to modofy your code so that it works with either control???
Thanks,
VB-Bandit | | bebandit Monday, January 30, 2006 1:03 PM | VB-Bandit,
The code above creates the PrintDocument now all you need to do is use it, the following code with give you a print preview!
Dim dlg As New PrintPreviewDialog()
dlg.Document = PrintDocument1
dlg.ShowDialog()
This code gives you the page setup form...
Dim psDlg As New PageSetupDialog
Dim storedPageSettings As PageSettings = New PageSettings()
psDlg.PageSettings = storedPageSettings
psDlg.ShowDialog()
I hope this is what you were looking for!
CoNNect | | CoNNect Saturday, March 18, 2006 6:36 AM | Thanks Heaps for your code Will!!!
BTW, your code drops off the last line, it's fixed now as below:
| | CoNNect Saturday, March 18, 2006 6:54 AM | Private oStringFormat As StringFormat Private oStringFormatComboBox As StringFormat Private oButton As Button Private oCheckbox As CheckBox Private oComboBox As ComboBox
Private nTotalWidth As Int16 Private nRowPos As Int16 Private NewPage As Boolean Private nPageNo As Int16 Private Header As String = "Header Test" Private sUserName As String = "Will"
Private Sub PrintDocument1_BeginPrint(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintEventArgs) Handles PrintDocument1.BeginPrint
oStringFormat = New StringFormat oStringFormat.Alignment = StringAlignment.Near oStringFormat.LineAlignment = StringAlignment.Center oStringFormat.Trimming = StringTrimming.EllipsisCharacter
oStringFormatComboBox = New StringFormat oStringFormatComboBox.LineAlignment = StringAlignment.Center oStringFormatComboBox.FormatFlags = StringFormatFlags.NoWrap oStringFormatComboBox.Trimming = StringTrimming.EllipsisCharacter
oButton = New Button oCheckbox = New CheckBox oComboBox = New ComboBox
nTotalWidth = 0 For Each oColumn As DataGridViewColumn In DataGridView1.Columns
nTotalWidth += oColumn.Width
Next nPageNo = 1 NewPage = True nRowPos = 0
End Sub
Private Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
Static oColumnLefts As New ArrayList Static oColumnWidths As New ArrayList Static oColumnTypes As New ArrayList Static nHeight As Int16
Dim nWidth, i, nRowsPerPage As Int16 Dim nTop As Int16 = e.MarginBounds.Top Dim nLeft As Int16 = e.MarginBounds.Left
If nPageNo = 1 Then
For Each oColumn As DataGridViewColumn In DataGridView1.Columns
nWidth = CType(Math.Floor(oColumn.Width / nTotalWidth * nTotalWidth * (e.MarginBounds.Width / nTotalWidth)), Int16)
nHeight = e.Graphics.MeasureString(oColumn.HeaderText, oColumn.InheritedStyle.Font, nWidth).Height + 11
oColumnLefts.Add(nLeft) oColumnWidths.Add(nWidth) oColumnTypes.add(oColumn.GetType) nLeft += nWidth
Next
End If
Do While nRowPos < DataGridView1.Rows.Count - 1
Dim oRow As DataGridViewRow = DataGridView1.Rows(nRowPos)
If nTop + nHeight >= e.MarginBounds.Height + e.MarginBounds.Top Then
DrawFooter(e, nRowsPerPage)
NewPage = True nPageNo += 1 e.HasMorePages = True Exit Sub
Else
If NewPage Then
' Draw Header e.Graphics.DrawString(Header, New Font(DataGridView1.Font, FontStyle.Bold), Brushes.Black, e.MarginBounds.Left, e.MarginBounds.Top - e.Graphics.MeasureString(Header, New Font(DataGridView1.Font, FontStyle.Bold), e.MarginBounds.Width).Height - 13)
' Draw Columns nTop = e.MarginBounds.Top i = 0 For Each oColumn As DataGridViewColumn In DataGridView1.Columns
e.Graphics.FillRectangle(New SolidBrush(Drawing.Color.LightGray), New Rectangle(oColumnLefts(i), nTop, oColumnWidths(i), nHeight)) e.Graphics.DrawRectangle(Pens.Black, New Rectangle(oColumnLefts(i), nTop, oColumnWidths(i), nHeight)) e.Graphics.DrawString(oColumn.HeaderText, oColumn.InheritedStyle.Font, New SolidBrush(oColumn.InheritedStyle.ForeColor), New RectangleF(oColumnLefts(i), nTop, oColumnWidths(i), nHeight), oStringFormat) i += 1
Next NewPage = False
End If
nTop += nHeight i = 0 For Each oCell As DataGridViewCell In oRow.Cells
If oColumnTypes(i) Is GetType(DataGridViewTextBoxColumn) OrElse oColumnTypes(i) Is GetType(DataGridViewLinkColumn) Then
e.Graphics.DrawString(oCell.Value.ToString, oCell.InheritedStyle.Font, New SolidBrush(oCell.InheritedStyle.ForeColor), New RectangleF(oColumnLefts(i), nTop, oColumnWidths(i), nHeight), oStringFormat)
ElseIf oColumnTypes(i) Is GetType(DataGridViewButtonColumn) Then
oButton.Text = oCell.Value.ToString oButton.Size = New Size(oColumnWidths(i), nHeight) Dim oBitmap As New Bitmap(oButton.Width, oButton.Height) oButton.DrawToBitmap(oBitmap, New Rectangle(0, 0, oBitmap.Width, oBitmap.Height)) e.Graphics.DrawImage(oBitmap, New Point(oColumnLefts(i), nTop))
ElseIf oColumnTypes(i) Is GetType(DataGridViewCheckBoxColumn) Then
oCheckbox.Size = New Size(14, 14) oCheckbox.Checked = CType(oCell.Value, Boolean) Dim oBitmap As New Bitmap(oColumnWidths(i), nHeight) Dim oTempGraphics As Graphics = Graphics.FromImage(oBitmap) oTempGraphics.FillRectangle(Brushes.White, New Rectangle(0, 0, oBitmap.Width, oBitmap.Height)) oCheckbox.DrawToBitmap(oBitmap, New Rectangle(CType((oBitmap.Width - oCheckbox.Width) / 2, Int32), CType((oBitmap.Height - oCheckbox.Height) / 2, Int32), oCheckbox.Width, oCheckbox.Height)) e.Graphics.DrawImage(oBitmap, New Point(oColumnLefts(i), nTop))
ElseIf oColumnTypes(i) Is GetType(DataGridViewComboBoxColumn) Then
oComboBox.Size = New Size(oColumnWidths(i), nHeight) Dim oBitmap As New Bitmap(oComboBox.Width, oComboBox.Height) oComboBox.DrawToBitmap(oBitmap, New Rectangle(0, 0, oBitmap.Width, oBitmap.Height)) e.Graphics.DrawImage(oBitmap, New Point(oColumnLefts(i), nTop)) e.Graphics.DrawString(oCell.Value.ToString, oCell.InheritedStyle.Font, New SolidBrush(oCell.InheritedStyle.ForeColor), New RectangleF(oColumnLefts(i) + 1, nTop, oColumnWidths(i) - 16, nHeight), oStringFormatComboBox)
ElseIf oColumnTypes(i) Is GetType(DataGridViewImageColumn) Then
Dim oCellSize As Rectangle = New Rectangle(oColumnLefts(i), nTop, oColumnWidths(i), nHeight) Dim oImageSize As Size = CType(oCell.Value, Image).Size e.Graphics.DrawImage(oCell.Value, New Rectangle(oColumnLefts(i) + CType(((oCellSize.Width - oImageSize.Width) / 2), Int32), nTop + CType(((oCellSize.Height - oImageSize.Height) / 2), Int32), CType(oCell.Value, Image).Width, CType(oCell.Value, Image).Height))
End If
e.Graphics.DrawRectangle(Pens.Black, New Rectangle(oColumnLefts(i), nTop, oColumnWidths(i), nHeight))
i += 1
Next
End If
nRowPos += 1 nRowsPerPage += 1
Loop
DrawFooter(e, nRowsPerPage)
e.HasMorePages = False
End Sub
Private Sub DrawFooter(ByVal e As System.Drawing.Printing.PrintPageEventArgs, ByVal RowsPerPage As Int32)
Dim sPageNo As String = nPageNo.ToString + " of " + Math.Ceiling(DataGridView1.Rows.Count / RowsPerPage).ToString
' Right Align - User Name e.Graphics.DrawString(sUserName, DataGridView1.Font, Brushes.Black, e.MarginBounds.Left + (e.MarginBounds.Width - e.Graphics.MeasureString(sPageNo, DataGridView1.Font, e.MarginBounds.Width).Width), e.MarginBounds.Top + e.MarginBounds.Height + 7)
' Left Align - Date/Time e.Graphics.DrawString(Now.ToLongDateString + " " + Now.ToShortTimeString, DataGridView1.Font, Brushes.Black, e.MarginBounds.Left, e.MarginBounds.Top + e.MarginBounds.Height + 7)
' Center - Page No. Info e.Graphics.DrawString(sPageNo, DataGridView1.Font, Brushes.Black, e.MarginBounds.Left + (e.MarginBounds.Width - e.Graphics.MeasureString(sPageNo, DataGridView1.Font, e.MarginBounds.Width).Width) / 2, e.MarginBounds.Top + e.MarginBounds.Height + 31)
End Sub | | CoNNect Saturday, March 18, 2006 7:23 AM | Hy guys.
I must say that this is a great code. But i get following error Error 1 Handles clause requires a WithEvents variable defined in the
containing type or one of its base types.
Private Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal
e As System.Drawing.Printing.PrintPageEventArgs) Handles
PrintDocument1.PrintPage
Problem
is with Handles PrintDocument1.PrintPage
Can you please tell me what i'm doing wrong?
Regards...
| | Nectuss Wednesday, March 22, 2006 5:46 PM | Ok i managed to solve
that. But now i got one serious problem! This code print all rows from
my DataGridView except last one. It always show one page more that
actually exist.
I have try your code too CoNNect but there is same problem with last row...
Some help will be very wellcome! | | Nectuss Wednesday, March 22, 2006 8:56 PM | Ok i have managed that too. If anyone will run into similar problem here is a way to set it right.
In while loop in posted code you must set Do While nRowPos < DataGridView1.Rows.Count - 1 you must delet -1. It should look like this Do While nRowPos < DataGridView1.Rows.Count. Then it will work just fine.
Great code indeed. Thank you...
| | Nectuss Wednesday, March 22, 2006 9:11 PM | This code was a HUGE help. Thank you...
I did add/change the following because I had a few empty cells and I was getting errors
For Each oCell As DataGridViewCell In oRow.Cells
If oCell.Value <> Nothing Then
sValue = oCell.Value.ToString
else
sValue = ""
End If
If oColumnTypes(i) Is GetType(DataGridViewTextBoxColumn) OrElse oColumnTypes(i) Is GetType(DataGridViewLinkColumn) Then
e.Graphics.DrawString(sValue, oCell.InheritedStyle.Font, New SolidBrush(oCell.InheritedStyle.ForeColor), New RectangleF(oColumnLefts(i), nTop, oColumnWidths(i), nHeight), oStringFormat) | | JeremyZK Friday, March 31, 2006 5:11 PM | Hey, That's great. I had the same problem and would like to know how you did. I tried but not as lucky as you. Help please! | | a3js Thursday, April 06, 2006 3:13 PM | is your problem about two pages on the same page? | | Ours Thursday, April 06, 2006 3:50 PM | If anyone is interested, I converted the code to C# and added a fix for correctly computing number of pages on the last page.
private StringFormat m_stringFormat;
private double m_totalWidth;
private int m_rowPos;
private bool m_newPage;
private int m_pageNo;
private string m_pageHeader = "Header";
private string m_userName = "Printed by <username>";
private ArrayList m_columnLefts = new ArrayList();
private ArrayList m_columnWidths = new ArrayList();
private int m_pageHeight = 0;
private int m_pageCount = 0;
private void printDocument1_BeginPrint(object sender, System.Drawing.Printing.PrintEventArgs e)
{
m_stringFormat = new StringFormat();
m_stringFormat.Alignment = StringAlignment.Near;
m_stringFormat.LineAlignment = StringAlignment.Center;
m_stringFormat.Trimming = StringTrimming.EllipsisCharacter;
m_totalWidth = 0;
foreach (DataGridViewColumn oColumn in dataGridView1.Columns)
{
m_totalWidth += oColumn.Width;
}
m_pageNo = 1;
m_newPage = true;
m_rowPos = 0;
}
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
int nWidth, i;
double nRowsPerPage = 0;
int nTop = e.MarginBounds.Top;
int nLeft = e.MarginBounds.Left;
if (m_pageNo == 1)
{
m_columnLefts.Clear();
m_columnWidths.Clear();
m_pageHeight = 0;
m_pageCount = 0;
foreach (DataGridViewColumn oColumn in dataGridView1.Columns)
{
double floorVal = Convert.ToDouble( oColumn.Width ) / m_totalWidth * m_totalWidth * (Convert.ToDouble( e.MarginBounds.Width) / m_totalWidth);
nWidth = Convert.ToInt32(Math.Floor(floorVal));
m_pageHeight = Convert.ToInt32(e.Graphics.MeasureString(oColumn.HeaderText, oColumn.InheritedStyle.Font, nWidth).Height) + 11;
m_columnLefts.Add(nLeft);
m_columnWidths.Add(nWidth);
nLeft += nWidth;
}
}
while (m_rowPos < dataGridView1.Rows.Count )
{
DataGridViewRow oRow = dataGridView1.Rows[m_rowPos];
if (nTop + m_pageHeight >= e.MarginBounds.Height + e.MarginBounds.Top)
{
DrawFooter(e, nRowsPerPage);
m_newPage = true;
m_pageNo++;
e.HasMorePages = true;
return;
}
else
{
if (m_newPage)
{
// Draw Header
e.Graphics.DrawString(m_pageHeader, new Font(dataGridView1.Font, FontStyle.Bold), Brushes.Black, e.MarginBounds.Left, e.MarginBounds.Top - e.Graphics.MeasureString(m_pageHeader, new Font(dataGridView1.Font, FontStyle.Bold), e.MarginBounds.Width).Height - 13);
// Draw Columns
nTop = e.MarginBounds.Top;
i = 0;
foreach (DataGridViewColumn oColumn in dataGridView1.Columns)
{
e.Graphics.FillRectangle( new SolidBrush(Color.LightGray), new Rectangle((int)m_columnLefts , nTop, (int)m_columnWidths , m_pageHeight));
e.Graphics.DrawRectangle( Pens.Black, new Rectangle((int)m_columnLefts , nTop, (int)m_columnWidths , m_pageHeight));
e.Graphics.DrawString(oColumn.HeaderText, oColumn.InheritedStyle.Font, new SolidBrush(oColumn.InheritedStyle.ForeColor), new RectangleF((int)m_columnLefts , nTop, (int)m_columnWidths , m_pageHeight), m_stringFormat);
i++;
}
m_newPage = false;
}
nTop += m_pageHeight;
i = 0;
foreach (DataGridViewCell oCell in oRow.Cells)
{
string sValue = String.Empty;
if (oCell.Value != null)
{
sValue = oCell.Value.ToString();
}
e.Graphics.DrawString(sValue, oCell.InheritedStyle.Font, new SolidBrush(oCell.InheritedStyle.ForeColor), new RectangleF((int)m_columnLefts , nTop, (int)m_columnWidths , m_pageHeight), m_stringFormat);
e.Graphics.DrawRectangle( Pens.Black, new Rectangle((int)m_columnLefts , nTop, (int)m_columnWidths , m_pageHeight));
i++;
}
}
m_rowPos++;
nRowsPerPage++;
}
DrawFooter(e, nRowsPerPage);
e.HasMorePages = false;
}
private void DrawFooter(System.Drawing.Printing.PrintPageEventArgs e, double nRowsPerPage)
{
if (m_pageCount == 0)
{
m_pageCount = Convert.ToInt32( Math.Ceiling(Convert.ToDouble(dataGridView1.Rows.Count) / nRowsPerPage) );
}
string sPageNo = String.Format("Page {0} of {1}", m_pageNo.ToString(), m_pageCount.ToString()).ToString();
// Right Align - User Name
e.Graphics.DrawString(m_userName, dataGridView1.Font, Brushes.Black, e.MarginBounds.Left + (e.MarginBounds.Width - e.Graphics.MeasureString(sPageNo, dataGridView1.Font, e.MarginBounds.Width).Width), e.MarginBounds.Top + e.MarginBounds.Height + 7);
// Left Align - Date/Time
e.Graphics.DrawString( DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToShortTimeString(), dataGridView1.Font, Brushes.Black, e.MarginBounds.Left, e.MarginBounds.Top + e.MarginBounds.Height + 7);
// Center - Page No. Info
e.Graphics.DrawString(sPageNo, dataGridView1.Font, Brushes.Black, e.MarginBounds.Left + (e.MarginBounds.Width - e.Graphics.MeasureString(sPageNo, dataGridView1.Font, e.MarginBounds.Width).Width) / 2, e.MarginBounds.Top + e.MarginBounds.Height + 31);
} | | Mark Duncan Monday, April 10, 2006 10:00 AM | | JeremyZK wrote: | |
If oCell.Value <> Nothing Then
|
|
Love the code!
One small change to handle dbnull:
If oCell.Value IsNot Nothing Then
or
If Not oCell.Value Is Nothing Then
- Proposed As Answer byStop_the_insanity Friday, May 01, 2009 2:43 PM
-
| | ottawaglen Friday, May 12, 2006 2:31 AM | Hi,
Have a look to this article 'DataGridViewPrinter Class':
http://www.codeproject.com/csharp/datagridviewprinter.asp
Salan | | Salan S. Al-Ani Thursday, May 18, 2006 9:02 PM | Hi,
Great Code! I Try to modify it because I need that it don't print a column if the property visible is set to false ... but I can't resolve the problem!
Anyone can help me?! Thanks so much :)
P.S. I Apologise for my bad english! | | Frankie82 Monday, June 12, 2006 11:06 AM | Hi Frankie,
Next time if you have question regarding the DataGridViewPrinter class, try to post it in the article page of that class:
http://www.codeproject.com/csharp/datagridviewprinter.asp
However, to solve your problem, just insert the below code in the beginning of the Calculate function of the class:
foreach (DataGridViewColumn col in TheDataGridView.Columns)
col.Visible = true;
Salan.. | | Salan S. Al-Ani Tuesday, June 13, 2006 8:54 AM | Excellent piece of code, does exactly what it is supposed to do, did have problem with not displaying last row but the deleteing of the -1 off count fixed problem. Thank you | | Shane Fay Friday, June 16, 2006 12:17 PM | After reading this post, I decided to give it the Print Grid solution a try (by will_affinity). I was able to get it to work. The Print Preview, Print Dialog, and Page Setup all worked as advertised, but I did rub into a slight problem that I am hoping someone in this discussion board can help me with.
If I select Print Preview, then close that window and select Page Setup and Perform another Print Preview, the grid maintains the same width as in Portrait. Whereas, if I start the program over, select Page Setup, change to Landscape, select Print Preview (document looks ok), select Page Setup, select Portrait, select Print Preview (document looks good), select Page Setup, change to Landscape, select Print Preview (document has bad margins again).
I'm sure this is not the best way to discribe what is happening, but since I am not to sure what I need to look for ...Oh well. I guess I sound confused and lost because I am. I have only been using Visual Basic (VS 2005) for about 6 months now, and I know I've only scratched the surface on what this stuff is capable of. Anyway, any help, comments, or directions would be greatly appreciated. Thank you in advance for your time and effort. | | pdelay Friday, June 30, 2006 7:40 PM | There's a problem with printing out the footer. It messes up the page number if the page has fewer than the max number of rows. For example, I had 38 rows spread over two pages, the first page said "Page 1 of 2" but the last one would say "Page 2 of 13" since there were only 3 rows on the final page. Either way, I've 'Option Stricted' and turned it into a class unto itself. Enjoy!
To Implement: Private Sub btnPrintPreview_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPrintPreview.Click If IsNothing(Printer) Then Printer = New Printer(dgvJobs, Me.Text, gblUserName) 'DataGridView, Wiindow Title (as the Page Header), Username End If Printer.ShowPrintPreviewDialog() End Sub
Private Sub btnPrint_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPrint.Click If IsNothing(Printer) Then Printer = New Printer(dgvJobs, Me.Text, gblUserName) 'DataGridView, Wiindow Title (as the Page Header), Username End If Printer.Print() End Sub
Public Class Printer Private oStringFormat As StringFormat Private oStringFormatComboBox As StringFormat Private oButton As Button Private oCheckbox As CheckBox Private oComboBox As ComboBox
Private nTotalWidth As Int16 Private nRowPos As Int16 Private NewPage As Boolean Private nPageNo As Int16 Private Header As String Private sUserName As String Private nPageCount As Integer = 0 Private dgv As DataGridView Private WithEvents PrintDoc As New Printing.PrintDocument Private storedPageSettings As Printing.PageSettings = New Printing.PageSettings()
Property DataGridViewToPrint() As DataGridView Get Return dgv End Get Set(ByVal value As DataGridView) dgv = value End Set End Property Property UserName() As String Get Return sUserName End Get Set(ByVal value As String) sUserName = value End Set End Property Property HeaderText() As String Get Return Header End Get Set(ByVal value As String) Header = value End Set End Property
Public Sub New(ByVal aDGV As DataGridView, ByVal aHeader As String, ByVal aUserName As String) DataGridViewToPrint = aDGV UserName = aUserName HeaderText = aHeader End Sub Public Sub Print() Dim psDlg As New PageSetupDialog psDlg.PageSettings = storedPageSettings psDlg.ShowDialog() End Sub Public Sub ShowPrintPreviewDialog() Dim dlg As New PrintPreviewDialog() dlg.Document = PrintDoc dlg.ShowDialog() End Sub Private Sub PrintDoc_BeginPrint(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintEventArgs) Handles PrintDoc.BeginPrint
oStringFormat = New StringFormat oStringFormat.Alignment = StringAlignment.Near oStringFormat.LineAlignment = StringAlignment.Center oStringFormat.Trimming = StringTrimming.EllipsisCharacter
oStringFormatComboBox = New StringFormat oStringFormatComboBox.LineAlignment = StringAlignment.Center oStringFormatComboBox.FormatFlags = StringFormatFlags.NoWrap oStringFormatComboBox.Trimming = StringTrimming.EllipsisCharacter
oButton = New Button oCheckbox = New CheckBox oComboBox = New ComboBox
nTotalWidth = 0 For Each oColumn As DataGridViewColumn In DataGridViewToPrint.Columns
nTotalWidth = CShort(nTotalWidth + oColumn.Width)
Next nPageNo = 1 NewPage = True nRowPos = 0
End Sub
Private Sub Printdoc_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDoc.PrintPage
Static oColumnLefts As New ArrayList Static oColumnWidths As New ArrayList Static oColumnTypes As New ArrayList Static nHeight As Int16
Dim nWidth, i, nRowsPerPage As Int16 Dim nTop As Int16 = CShort(e.MarginBounds.Top) Dim nLeft As Int16 = CShort(e.MarginBounds.Left)
If nPageNo = 1 Then
For Each oColumn As DataGridViewColumn In DataGridViewToPrint.Columns
nWidth = CType(Math.Floor(oColumn.Width / nTotalWidth * nTotalWidth * (e.MarginBounds.Width / nTotalWidth)), Int16)
nHeight = CShort(e.Graphics.MeasureString(oColumn.HeaderText, oColumn.InheritedStyle.Font, nWidth).Height + 11)
oColumnLefts.Add(nLeft) oColumnWidths.Add(nWidth) oColumnTypes.Add(oColumn.GetType) nLeft += nWidth
Next
End If
Do While nRowPos < DataGridViewToPrint.Rows.Count
Dim oRow As DataGridViewRow = DataGridViewToPrint.Rows(nRowPos)
If nTop + nHeight >= e.MarginBounds.Height + e.MarginBounds.Top Then
DrawFooter(e, nRowsPerPage)
NewPage = True nPageNo = CShort(nPageNo + 1) e.HasMorePages = True Exit Sub
Else
If NewPage Then
' Draw Header e.Graphics.DrawString(Header, New Font(DataGridViewToPrint.Font, FontStyle.Bold), Brushes.Black, e.MarginBounds.Left, e.MarginBounds.Top - e.Graphics.MeasureString(Header, New Font(DataGridViewToPrint.Font, FontStyle.Bold), e.MarginBounds.Width).Height - 13)
' Draw Columns nTop = CShort(e.MarginBounds.Top) i = 0 For Each oColumn As DataGridViewColumn In DataGridViewToPrint.Columns
e.Graphics.FillRectangle(New SolidBrush(Drawing.Color.LightGray), New Rectangle(CInt(oColumnLefts(i)), nTop, CInt(oColumnWidths(i)), nHeight)) e.Graphics.DrawRectangle(Pens.Black, New Rectangle(CInt(oColumnLefts(i)), nTop, CInt(oColumnWidths(i)), nHeight)) e.Graphics.DrawString(oColumn.HeaderText, oColumn.InheritedStyle.Font, New SolidBrush(oColumn.InheritedStyle.ForeColor), New RectangleF(CSng(oColumnLefts(i)), nTop, CSng(oColumnWidths(i)), nHeight), oStringFormat) i = CShort(i + 1)
Next NewPage = False
End If
nTop += nHeight i = 0 For Each oCell As DataGridViewCell In oRow.Cells
If oColumnTypes(i) Is GetType(DataGridViewTextBoxColumn) OrElse oColumnTypes(i) Is GetType(DataGridViewLinkColumn) Then
e.Graphics.DrawString(oCell.Value.ToString, oCell.InheritedStyle.Font, New SolidBrush(oCell.InheritedStyle.ForeColor), New RectangleF(CSng(oColumnLefts(i)), nTop, CSng(oColumnWidths(i)), nHeight), oStringFormat)
ElseIf oColumnTypes(i) Is GetType(DataGridViewButtonColumn) Then
oButton.Text = oCell.Value.ToString oButton.Size = New Size(CInt(oColumnWidths(i)), nHeight) Dim oBitmap As New Bitmap(oButton.Width, oButton.Height) oButton.DrawToBitmap(oBitmap, New Rectangle(0, 0, oBitmap.Width, oBitmap.Height)) e.Graphics.DrawImage(oBitmap, New Point(CInt(oColumnLefts(i)), nTop))
ElseIf oColumnTypes(i) Is GetType(DataGridViewCheckBoxColumn) Then
oCheckbox.Size = New Size(14, 14) oCheckbox.Checked = CType(oCell.Value, Boolean) Dim oBitmap As New Bitmap(CInt(oColumnWidths(i)), nHeight) Dim oTempGraphics As Graphics = Graphics.FromImage(oBitmap) oTempGraphics.FillRectangle(Brushes.White, New Rectangle(0, 0, oBitmap.Width, oBitmap.Height)) oCheckbox.DrawToBitmap(oBitmap, New Rectangle(CType((oBitmap.Width - oCheckbox.Width) / 2, Int32), CType((oBitmap.Height - oCheckbox.Height) / 2, Int32), oCheckbox.Width, oCheckbox.Height)) e.Graphics.DrawImage(oBitmap, New Point(CInt(oColumnLefts(i)), nTop))
ElseIf oColumnTypes(i) Is GetType(DataGridViewComboBoxColumn) Then
oComboBox.Size = New Size(CInt(oColumnWidths(i)), nHeight) Dim oBitmap As New Bitmap(oComboBox.Width, oComboBox.Height) oComboBox.DrawToBitmap(oBitmap, New Rectangle(0, 0, oBitmap.Width, oBitmap.Height)) e.Graphics.DrawImage(oBitmap, New Point(CInt(oColumnLefts(i)), nTop)) e.Graphics.DrawString(oCell.Value.ToString, oCell.InheritedStyle.Font, New SolidBrush(oCell.InheritedStyle.ForeColor), New RectangleF(CInt(oColumnLefts(i)) + 1, nTop, CInt(oColumnWidths(i)) - 16, nHeight), oStringFormatComboBox)
ElseIf oColumnTypes(i) Is GetType(DataGridViewImageColumn) Then
Dim oCellSize As Rectangle = New Rectangle(CInt(oColumnLefts(i)), nTop, CInt(oColumnWidths(i)), nHeight) Dim oImageSize As Size = CType(oCell.Value, Image).Size e.Graphics.DrawImage(CType(oCell.Value, Image), New Rectangle(CType(oColumnLefts(i), Int32) + CType(((oCellSize.Width - oImageSize.Width) / 2), Int32), nTop + CType(((oCellSize.Height - oImageSize.Height) / 2), Int32), CType(oCell.Value, Image).Width, CType(oCell.Value, Image).Height))
End If
e.Graphics.DrawRectangle(Pens.Black, New Rectangle(CInt(oColumnLefts(i)), nTop, CInt(oColumnWidths(i)), nHeight))
i = CShort(i + 1)
Next
End If
nRowPos = CShort(nRowPos + 1) nRowsPerPage = CShort(nRowsPerPage + 1) Loop
DrawFooter(e, nRowsPerPage)
e.HasMorePages = False
End Sub
Private Sub DrawFooter(ByVal e As System.Drawing.Printing.PrintPageEventArgs, ByVal RowsPerPage As Int32)
'Changed from Page XXX of XXX to just Page XXX because 'Math.Ceiling(DataGridViewToPrint.Rows.Count / RowsPerPage).ToString() would generate 'inaccurate page numbers on pages with less than the max number of rows (ie: the last page) 'Dim sPageNo As String = nPageNo.ToString + " of " + Math.Ceiling(DataGridViewToPrint.Rows.Count / RowsPerPage).ToString Dim sPageNo As String = "Page " + nPageNo.ToString
' Right Align - User Name e.Graphics.DrawString("Printed by: " + sUserName, DataGridViewToPrint.Font, Brushes.Black, e.MarginBounds.Left + (e.MarginBounds.Width - e.Graphics.MeasureString(sPageNo, DataGridViewToPrint.Font, e.MarginBounds.Width).Width), e.MarginBounds.Top + e.MarginBounds.Height + 7)
' Left Align - Date/Time e.Graphics.DrawString(Now.ToLongDateString + " " + Now.ToShortTimeString, DataGridViewToPrint.Font, Brushes.Black, e.MarginBounds.Left, e.MarginBounds.Top + e.MarginBounds.Height + 7)
' Center - Page No. Info e.Graphics.DrawString(sPageNo, DataGridViewToPrint.Font, Brushes.Black, e.MarginBounds.Left + (e.MarginBounds.Width - e.Graphics.MeasureString(sPageNo, DataGridViewToPrint.Font, e.MarginBounds.Width).Width) / 2, e.MarginBounds.Top + e.MarginBounds.Height + 31)
End Sub End Class
| | Forkbeard Tuesday, July 04, 2006 7:39 PM | hey,
i tried your code but it is giving me compiling errors
Error1Handles clause requires a WithEvents variable defined in the containing type or one of its base {ERROR OCCURED IN BTN[PREVIEW CLICK EVENT}
Error2'Printer' is a type and cannot be used as an expression.{IN THE SAME EVENT :
If IsNothing(Printer) Then
Printer = New Printer(DataGridView1, Me.Text, "shrey") 'DataGridView, Wiindow Title (as the Page Header), Username
End If
Printer.ShowPrintPreviewDialog()
}
Error8Reference to a non-shared member requires an object reference.
Printer.Print()
Could you help me i am new at vb.
thnks in advance
Shrey Sharma
| | Shrekage Tuesday, July 11, 2006 3:03 PM | DrawFooter(e, nPageNo);
after the main row loop rather than
DrawFooter(e, nRowsPerPage);
eliminates the problem when the page has fewer than the max rows too.
| | angrylala Monday, July 31, 2006 6:36 AM | How do I call this from a button?
Regards
Sabe75 | | sabe75 Wednesday, August 09, 2006 11:55 AM | Thanks Guys,
Its a really a great code. My heartful Thanks to those guys who did the program. please update for new codings and projects.
vimalbtechit2005@gmail.com
Vimal.
| | VimalRocks Monday, August 21, 2006 11:30 AM | Hey I am relativly new to VB.Net, love the code, just one question. I have a DGV with 24 columns, I do not want to print all the columns how could I set it up just to print the first 9 columns? Please help thanks in advance! | | Dragonspire Monday, October 16, 2006 3:00 AM | Dim sPageNo As String = nPageNo.ToString + " of " + Math.Ceiling(DataGridViewToPrint.Rows.Count / RowsPerPage).ToString
I changed the above code in Sub DrawFooter to:
________________________________________________________________________
Dim sPageNo As String
If blnGotNumPages = False Then
blnGotNumPages = True
strNumOfPages = Math.Ceiling(DataGridView1.Rows.Count / RowsPerPage).ToString
sPageNo = nPageNo.ToString + " of " + Math.Ceiling(DataGridView1.Rows.Count / RowsPerPage).ToString
Else
sPageNo = nPageNo.ToString + " of " + strNumOfPages
End If
______________________________________________________________________________________________
Ofcourse I declared blnGotNumPages and strNumOfPages outside of the Sub, and made blnGotNumPages = False when the print Preview btn was clicked.
This solution will give you Page x of y correctly. Even for the last page. I hope this was helpful to some of you all.
Thomas
| | thomasvanderhoof Thursday, November 16, 2006 3:39 PM | Getting the same errors, did anyone figure it out? Printer is a class. Cant imagine why it would bring the error:
'Printer' is a type and cannot be used as an expression.
Thanks.
| | Naven626LX Thursday, December 07, 2006 4:09 PM | Hi,
Hi, I like the Code and I also saw the code project Printing class. Here is a version that uses static methods and auto generates the print document internally. This way you can just call: PrintFactory.Print() or PrintFactory.Preview() from anywhere and not worry about instances. Obviously, you can expand on this code in a million ways, but it is start for clean library for datagridview printing.
Imports System.Windows.Forms
Public Class PrintFactory
# Region "Instance"
# Region "Declerations"
Private WithEvents _printDocument As Printing.PrintDocument = _
New Printing.PrintDocument()
Private _dgv As DataGridView
Private _stringFormat As StringFormat
Private _stringFormatComboBox As StringFormat
Private _button As Button
Private _checkBox As CheckBox
Private _comboBox As ComboBox
Private _totalWidth As Int16
Private _rowPos As Int16
Private _newPage As Boolean
Private _pageNumber As Int16
Private _userName As String
Private _headerText As String
# End Region
# Region "Properties"
Private ReadOnly Property DGV() As DataGridView
Get
Return _dgv
End Get
End Property
Private Property HeaderText() As String
Get
Return _headerText
End Get
Set(ByVal value As String)
_headerText = value
End Set
End Property
Private Property UserName() As String
Get
Return _userName
End Get
Set(ByVal value As String)
_userName = value
End Set
End Property
Private Property StringFormat() As StringFormat
Get
Return _stringFormat
End Get
Set(ByVal value As StringFormat)
_stringFormat = value
End Set
End Property
Private Property StringFormatComboBox() As StringFormat
Get
Return _stringFormatComboBox
End Get
Set(ByVal value As StringFormat)
_stringFormatComboBox = value
End Set
End Property
Private Property Button() As Button
Get
Return _button
End Get
Set(ByVal value As Button)
_button = value
End Set
End Property
Private Property CheckBox() As CheckBox
Get
Return _checkBox
End Get
Set(ByVal value As CheckBox)
_checkBox = value
End Set
End Property
Private Property ComboBox() As ComboBox
Get
Return _comboBox
End Get
Set(ByVal value As ComboBox)
_comboBox = value
End Set
End Property
Private Property TotalWidth() As Int16
Get
Return _totalWidth
End Get
Set(ByVal value As Int16)
_totalWidth = value
End Set
End Property
Private Property RowPos() As Int16
Get
Return _rowPos
End Get
Set(ByVal value As Int16)
_rowPos = value
End Set
End Property
Private Property NewPage() As Boolean
Get
Return _newPage
End Get
Set(ByVal value As Boolean)
_newPage = value
End Set
End Property
Private Property PageNumber() As Int16
Get
Return _pageNumber
End Get
Set(ByVal value As Int16)
_pageNumber = value
End Set
End Property
# End Region
Private Sub New(ByVal userName As String, _
ByVal headerText As String)
Me._userName = userName
Me._headerText = headerText
End Sub
Private Sub _printDocument_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles _printDocument.PrintPage
EndPrint( Me, e)
End Sub
# End Region
# Region "Statics"
Public Shared Function Print(ByVal dgv As DataGridView, _
ByVal userName As String, _
ByVal headerText As String) As Boolean
Validate(dgv, userName, headerText)
Dim tempPrintFactory As PrintFactory = BeginPrint(dgv, userName, headerText)
tempPrintFactory._printDocument.Print()
End Function
Public Shared Function Preview(ByVal dgv As DataGridView, _
ByVal userName As String, _
ByVal headerText As String) As Boolean
Validate(dgv, userName, headerText)
Dim tempPrintFactory As PrintFactory = BeginPrint(dgv, userName, headerText)
Dim tempPrintDiag As New PrintPreviewDialog()
tempPrintDiag.Document = tempPrintFactory._printDocument
tempPrintDiag.ShowDialog()
End Function
Private Shared Function BeginPrint(ByVal dgv As DataGridView, ByVal userName As String, ByVal headerText As String) As PrintFactory
Dim printEntity As PrintFactory = New PrintFactory(userName, headerText)
printEntity._dgv = dgv
printEntity.StringFormat = New StringFormat
printEntity.StringFormat.Alignment = StringAlignment.Near
printEntity.StringFormat.LineAlignment = StringAlignment.Center
printEntity.StringFormat.Trimming = StringTrimming.EllipsisCharacter
printEntity.StringFormatComboBox = New StringFormat
printEntity.StringFormatComboBox.LineAlignment = StringAlignment.Center
printEntity.StringFormatComboBox.FormatFlags = StringFormatFlags.NoWrap
printEntity.StringFormatComboBox.Trimming = StringTrimming.EllipsisCharacter
printEntity.Button = New Button
printEntity.CheckBox = New CheckBox
printEntity.ComboBox = New ComboBox
printEntity.TotalWidth = 0
For Each oColumn As DataGridViewColumn In dgv.Columns
printEntity.TotalWidth += oColumn.Width
Next
printEntity.PageNumber = 1
printEntity.NewPage = True
printEntity.RowPos = 0
Return printEntity
End Function
Private Shared Function EndPrint(ByVal printEntity As PrintFactory, _
ByVal e As System.Drawing.Printing.PrintPageEventArgs) As Boolean
Dim oColumnLefts As New ArrayList
Dim oColumnWidths As New ArrayList
Dim oColumnTypes As New ArrayList
Dim nHeight As Int16
Dim nWidth, i, nRowsPerPage As Int16
Dim nTop As Int16 = e.MarginBounds.Top
Dim nLeft As Int16 = e.MarginBounds.Left
If printEntity.PageNumber = 1 Then
For Each oColumn As DataGridViewColumn In printEntity.DGV.Columns
nWidth = CType(Math.Floor(oColumn.Width / printEntity.TotalWidth * printEntity.TotalWidth * (e.MarginBounds.Width / printEntity.TotalWidth)), Int16)
nHeight = e.Graphics.MeasureString(oColumn.HeaderText, oColumn.InheritedStyle.Font, nWidth).Height + 11
oColumnLefts.Add(nLeft)
oColumnWidths.Add(nWidth)
oColumnTypes.Add(oColumn.GetType)
nLeft += nWidth
Next
End If
Do While printEntity.RowPos < printEntity.DGV.Rows.Count - 1
Dim oRow As DataGridViewRow = printEntity.DGV.Rows(printEntity.RowPos)
If nTop + nHeight >= e.MarginBounds.Height + e.MarginBounds.Top Then
DrawFooter(printEntity.DGV, printEntity, nRowsPerPage, e)
printEntity.NewPage = True
printEntity.PageNumber += 1
e.HasMorePages = True
Exit Function
Else
If printEntity.NewPage Then
' Draw Header
e.Graphics.DrawString(printEntity.HeaderText, New Font(printEntity.DGV.Font, FontStyle.Bold), Brushes.Black, e.MarginBounds.Left, e.MarginBounds.Top - e.Graphics.MeasureString(printEntity.HeaderText, New Font(printEntity.DGV.Font, FontStyle.Bold), e.MarginBounds.Width).Height - 13)
' Draw Columns
nTop = e.MarginBounds.Top
i = 0
For Each oColumn As DataGridViewColumn In printEntity.DGV.Columns
e.Graphics.FillRectangle( New SolidBrush(Drawing.Color.LightGray), New Rectangle(oColumnLefts(i), nTop, oColumnWidths(i), nHeight))
e.Graphics.DrawRectangle(Pens.Black, New Rectangle(oColumnLefts(i), nTop, oColumnWidths(i), nHeight))
e.Graphics.DrawString(oColumn.HeaderText, oColumn.InheritedStyle.Font, New SolidBrush(oColumn.InheritedStyle.ForeColor), New RectangleF(oColumnLefts(i), nTop, oColumnWidths(i), nHeight), printEntity.StringFormat)
i += 1
Next
printEntity.NewPage = False
End If
nTop += nHeight
i = 0
For Each oCell As DataGridViewCell In oRow.Cells
If oColumnTypes(i) Is GetType(DataGridViewTextBoxColumn) OrElse oColumnTypes(i) Is GetType(DataGridViewLinkColumn) Then
e.Graphics.DrawString(oCell.Value.ToString, oCell.InheritedStyle.Font, New SolidBrush(oCell.InheritedStyle.ForeColor), New RectangleF(oColumnLefts(i), nTop, oColumnWidths(i), nHeight), printEntity.StringFormat)
ElseIf oColumnTypes(i) Is GetType(DataGridViewButtonColumn) Then
printEntity.Button.Text = oCell.Value.ToString
printEntity.Button.Size = New Size(oColumnWidths(i), nHeight)
Dim oBitmap As New Bitmap(printEntity.Button.Width, printEntity.Button.Height)
printEntity.Button.DrawToBitmap(oBitmap, New Rectangle(0, 0, oBitmap.Width, oBitmap.Height))
e.Graphics.DrawImage(oBitmap, New Point(oColumnLefts(i), nTop))
ElseIf oColumnTypes(i) Is GetType(DataGridViewCheckBoxColumn) Then
printEntity.CheckBox.Size = New Size(14, 14)
printEntity.CheckBox.Checked = CType(oCell.Value, Boolean)
Dim oBitmap As New Bitmap(oColumnWidths(i), nHeight)
Dim oTempGraphics As Graphics = Graphics.FromImage(oBitmap)
oTempGraphics.FillRectangle(Brushes.White, New Rectangle(0, 0, oBitmap.Width, oBitmap.Height))
printEntity.CheckBox.DrawToBitmap(oBitmap, New Rectangle(CType((oBitmap.Width - printEntity.CheckBox.Width) / 2, Int32), CType((oBitmap.Height - printEntity.CheckBox.Height) / 2, Int32), printEntity.CheckBox.Width, printEntity.CheckBox.Height))
e.Graphics.DrawImage(oBitmap, New Point(oColumnLefts(i), nTop))
ElseIf oColumnTypes(i) Is GetType(DataGridViewComboBoxColumn) Then
printEntity.ComboBox.Size = New Size(oColumnWidths(i), nHeight)
Dim oBitmap As New Bitmap(printEntity.ComboBox.Width, printEntity.ComboBox.Height)
printEntity.ComboBox.DrawToBitmap(oBitmap, New Rectangle(0, 0, oBitmap.Width, oBitmap.Height))
e.Graphics.DrawImage(oBitmap, New Point(oColumnLefts(i), nTop))
e.Graphics.DrawString(oCell.Value.ToString, oCell.InheritedStyle.Font, New SolidBrush(oCell.InheritedStyle.ForeColor), New RectangleF(oColumnLefts(i) + 1, nTop, oColumnWidths(i) - 16, nHeight), printEntity.StringFormatComboBox)
ElseIf oColumnTypes(i) Is GetType(DataGridViewImageColumn) Then
Dim oCellSize As Rectangle = New Rectangle(oColumnLefts(i), nTop, oColumnWidths(i), nHeight)
Dim oImageSize As Size = CType(oCell.Value, Image).Size
e.Graphics.DrawImage(oCell.Value, New Rectangle(oColumnLefts(i) + CType(((oCellSize.Width - oImageSize.Width) / 2), Int32), nTop + CType(((oCellSize.Height - oImageSize.Height) / 2), Int32), CType(oCell.Value, Image).Width, CType(oCell.Value, Image).Height))
End If
e.Graphics.DrawRectangle(Pens.Black, New Rectangle(oColumnLefts(i), nTop, oColumnWidths(i), nHeight))
i += 1
Next
End If
printEntity.RowPos += 1
nRowsPerPage += 1
Loop
DrawFooter(printEntity.DGV, printEntity, nRowsPerPage, e)
e.HasMorePages = False
End Function
Private Shared Function DrawFooter(ByVal dgv As DataGridView, _
ByVal printEntity As PrintFactory, _
ByVal RowsPerPage As Int32, _
ByVal e As System.Drawing.Printing.PrintPageEventArgs) As Boolean
Dim sPageNo As String = printEntity.PageNumber.ToString + " of " + Math.Ceiling(dgv.Rows.Count / RowsPerPage).ToString
' Right Align - User Name
e.Graphics.DrawString(printEntity.UserName, dgv.Font, Brushes.Black, e.MarginBounds.Left + (e.MarginBounds.Width - e.Graphics.MeasureString(sPageNo, dgv.Font, e.MarginBounds.Width).Width), e.MarginBounds.Top + e.MarginBounds.Height + 7)
' Left Align - Date/Time
e.Graphics.DrawString(Now.ToLongDateString + " " + Now.ToShortTimeString, dgv.Font, Brushes.Black, e.MarginBounds.Left, e.MarginBounds.Top + e.MarginBounds.Height + 7)
' Center - Page No. Info
e.Graphics.DrawString(sPageNo, dgv.Font, Brushes.Black, e.MarginBounds.Left + (e.MarginBounds.Width - e.Graphics.MeasureString(sPageNo, dgv.Font, e.MarginBounds.Width).Width) / 2, e.MarginBounds.Top + e.MarginBounds.Height + 31)
End Function
Private Shared Sub Validate(ByVal dgv As DataGridView, _
ByVal userName As String, _
ByVal headerText As String)
If dgv Is Nothing Then
Throw New ArgumentNullException("dgv")
End If
If String.IsNullOrEmpty(userName) = True Then
Throw New ArgumentNullException("userName")
End If
If String.IsNullOrEmpty(headerText) = True Then
Throw New ArgumentNullException("headerText")
End If
End Sub
# End Region
End Class | | yababer Wednesday, January 31, 2007 4:37 PM | I like this code but I seem to be having issues with an error. Have you experienced this one.
Index was out of range. Must be non-negative and less than the size of the collection. The error is in the EndPrint function.
For Each oColumn As DataGridViewColumn In printEntity.DGV.Columns
Error in this line >>>> e.Graphics.FillRectangle(New SolidBrush(Drawing.Color.LightGray), New Rectangle(oColumnLefts(i), nTop, oColumnWidths(i), nHeight))
e.Graphics.DrawRectangle(Pens.Black, New Rectangle(oColumnLefts(i), nTop, oColumnWidths(i), nHeight))
e.Graphics.DrawString(oColumn.HeaderText, oColumn.InheritedStyle.Font, New SolidBrush(oColumn.InheritedStyle.ForeColor), New RectangleF(oColumnLefts(i), nTop, oColumnWidths(i), nHeight), printEntity.StringFormat)
i += 1
Next
| | crortiz Friday, March 02, 2007 9:32 PM |
Hi,
I have tried your code. It is working very well. I wanted one enhancement in that.
I tried even but that code after modification seems to be meshy. If you please look into what is my requirement and yes how it would be adjusted in the similar code.
The requirement is : It should print the grid element like excel which means it should split the column after it reaches to page bounds.
| | A.S Ansh Wednesday, March 14, 2007 10:21 AM | sorry, it doesn't solve the problem.
what I do it just change a little code in "Sub Printdoc_PrintPage"
from
Do While nRowPos < DataGridViewToPrint.Rows.Count
to
Do While nRowPos < DataGridViewToPrint.Rows.Count - 1 | | erw13n Monday, March 26, 2007 12:12 PM |
Thanks to all that have contributed to this code.
I had an issue with Forkbeard's code and the hardcopy document not actually printing.
So I changed the "Print" subrouting in the above code to:-
Code Snippet
Public Sub Print()
' Remmed srowan 20070403. Forkbeard's original code posted to MSDN forum is below and commented.
'Dim psDlg As New PageSetupDialog
'psDlg.PageSettings = storedPageSettings
'psDlg.ShowDialog()
' Modified srowan 20070403. Above code was not printing the document. Modified to perform action after showing the dialog. Also changed from Page Setup Dialog to Printer Dialog.
Dim dlg As New PrintDialog()
dlg.Document = PrintDoc
Dim result As DialogResult = dlg.ShowDialog()
If (result = System.Windows.Forms.DialogResult.OK) Then
PrintDoc.Print()
End If
End Sub
Regards,
Scott
| | Scott Rowan Tuesday, April 03, 2007 1:02 AM | hellow!! I am new in VB2005 and i really have no idea about it..My on the job training superior ask me to make a program..I already finish some of the parts except the printing...I only used rich textbox, the copy/paste command the problem is the alignment.
please reply... thanks alot..godbless | | confused___ Tuesday, April 10, 2007 7:35 AM | Just replace
Do While nRowPos < DataGridView1.Rows.Count - 1
with
Do While nRowPos < DataGridView1.Rows.Count
| | jonawebb Tuesday, May 29, 2007 11:52 AM |
I've got a problem where one of the columns in the datagridview displays ONLY the date, but the print is printing the date plus '00:00:00'
Can anyone help me please with the code to displaying only the date ina format of 'dd/mm/yy' to the print document?
Thanks | | Gilberto74 Monday, June 18, 2007 12:59 PM | Just starting with VB Express
This helped a lot.
Have found that you need to destroy the static variables when finished or the next time you print preview it uses the same value even if you change the column width s etc.
Also found that you need to check for actual cell contents before printing text from a cell.
Easy done.
Great bit of code.
| | musicandstamps Wednesday, July 25, 2007 11:54 AM |
The static approach is interesting. Buster has another approach using vb, that prints the grid as seen on the screen.
I've modified it for c# too. | | tec-goblin Tuesday, August 07, 2007 11:29 AM |
hey all. after long time and nearly null results on vb2005 and datagridview printing. i found this thread.. all works ok with some minor modifications.. but one or two problems still persists.
if too many columns then it squizes everything in one page.. cant get it on a second.. (not for rows.. but for columns)
and after that. if i preview lets say 5 columns and then 2.. the width of the table gets the whole page.. although its good in the beginning..
any help would be greatly appreciated..
as for the part that wouldnt print on landscape.. had the same problem as well nd i just got
e.PageSettings.Landscape = True
on the query page settings. or u can even get ur own radiobuttons for the user to have a choice..
thank u in advance | | cevk1 Friday, August 31, 2007 11:55 AM |
FTAO Will_Affinity
Your brain must be the size of a moon. I've copied your code into my program and it works perfect.
I can't thank you enough, you've saved me hours of headaches. If i could afford it i'd send you a cheque.
NoZparker | | NoZparker Thursday, September 06, 2007 10:04 AM | I'm still having trouble here.
The cell contents is only displaying the date format, which is what I want.
But when I do a print preview, it displays the date as well as '00:00:00'.
I'd like to remove the time.
Everything else works perfectly. 
| | Gilberto74 Thursday, September 06, 2007 6:37 PM | Hi folks, there is a free component that gives the printing functionality. This is something like pluggin for the DataGridView control itself - it just wraps it - also it gives you the functionalities of searching for an item in the DataGridView control, exporting datato HTML, Excel and Pdf and many more...
Check it out on http://www.completit.com/Products/DGVE/Overview.aspx
It thing that a lot ot hard work is done there. | | Alex_82 Wednesday, December 12, 2007 8:04 AM | Was a great post! I just paste it and works! Thank You Very Much Still I have some question for you. How should I do if I want the Header to be multiline. like: Title of the page Subtitle of the page Another thing where do I put the code so I can print it on landscape? And the last how can I manage the cell borders. Thats it, than you again for a great code.
| | bokzertq Wednesday, January 23, 2008 9:38 PM | How did you solve this problem? | | MysticPhoenix Tuesday, February 19, 2008 2:05 PM | I started with a need to print a DataGridView a couple of years ago and went down several pathways. However, I recently discovered a very sweet solution for printing a DataGridView and many other .Net objects. It is the Reporting Services control available for Visual Studio 2005 (Its also in 2008 but has a nasty bug!). It is an almost trivial task to construct a class to organises the DataGrid contents as a datasource to an RDL (Report Definition Language) based report. The RDL report has good capabilities for formatting, sorting, totalling, etc. Once the report is rendered to the user's screen, the user is able to print it, output to PDF or Excel. A really neat bit is the ability to created a drilldown report which puts more control back into the user's hands.
Do not get confused with server side reporting using Reporting Services. The VS control does not require any SQL Server components or licences. It is described with SQL Server Reporting Services because the RDL syntax and capabilities are almost identical.
| | GraemeWT Tuesday, February 19, 2008 9:42 PM | Does anyone know how to solve the Handles PrintDocument1.PrintPage problem?
Thanks | | Mindy Ferguson Wednesday, April 02, 2008 9:38 PM | Here you are a tool which can help you: GridDrawer.Net
| | blaise.braye Sunday, April 27, 2008 8:28 PM | My datagridveiw works perfect wth the above original code. except with the blank cell whicth returns an error. the above is still great
Thank you.
| | Curtis UN Tuesday, July 01, 2008 5:59 AM |
Hi,
Great work and really good one. But One suggetion, is it possible to convert to .NET 2.0.
Why because, Your control will be more usefull, If it is available for .NET 2.0 Applications. Please make it available, then it will be great. | | ram342562 Wednesday, July 02, 2008 3:42 PM | How did you fix the previous Handles PrintDocument1.PrintPage problem? I've got the same message. | | Jeff045 Saturday, July 05, 2008 10:27 AM | This is great. One question. How would i change the page settings so that i could change the paper type. I would like to be able to use this to print without a preview. how would i do that? thanks!
| | KillerVette Sunday, July 06, 2008 6:21 PM | How can i change columns width (for printing)? some of columns has wraper strings...
| | MaysamSh Wednesday, August 06, 2008 2:37 PM | If my understanding of this is correct You have to change the datagridview so that you can view the whole collum contents. The code just looks at the width of the collum that is viewed not the total of the contents. So adjust your collum width of data grid view so that when you see the data on screen you see all of it. Then the print routine will see the correct width. Hope this helps.
| | Curtis UN Wednesday, August 13, 2008 7:50 PM |
I am busy for a few month with a library which could help you to print DataGridView contents.
see http://www.codeplex.com/PrintDataGridViewand enjoy (I hope)  | | blaise.braye Wednesday, August 13, 2008 8:05 PM | Another small fix:
' Right Align - User Name
e.Graphics.DrawString(sUserName, dgv.Font, Brushes.Black, e.MarginBounds.Left + (e.MarginBounds.Width - e.Graphics.MeasureString(sUserName, dgv.Font, e.MarginBounds.Width).Width), e.MarginBounds.Top + e.MarginBounds.Height + 7)
| | Huugie Tuesday, August 19, 2008 12:08 PM | My friend connect . . .
i have a problem. . .
im using vb2008, and your code works great
but i have one problem with your code :
Dim psDlg As New PageSetupDialog
Dim storedPageSettings As PageSettings = New PageSettings()
psDlg.PageSettings = storedPageSettings
psDlg.ShowDialog()
that do not compile, i think there is a typo but i cannot find where . . .
the vb2008 do not even know pagesettings . . .
so this is my question
-
a) do you have an updated solution on how to print a grid from a form?
-
b) can you fix this code
-
c) how do i relate the page setupdialog with the print document?
my preview looks good, but the margings are too big, making some columns display too small
d) id there anyway to hide some columns . . .
Mr. White. . . | | Edwin Blancovitch Monday, September 15, 2008 9:28 PM |
May be youcouldtry the solution I implemented...
http://www.codeplex.com/PrintYourGridsDotNet
Have a nice evening | | blaise.braye Monday, September 15, 2008 9:35 PM | Private Sub PrintDocument1_BeginPrint(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintEventArgs) Handles PrintDocument1.BeginPrint
Private Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
I too am getting the Handles clause requires a WithEvents variable defined in the containing type or one of its base types. error. Can someone please explain what those of us (there seem to be several) who are getting this message are missing?
| | DigitalFusion Tuesday, September 16, 2008 5:13 AM | I have taken snippits from all over this forum and have been successful in printing out my datagrid exactly how i want it.
i can print :-
All
Odds
Evens
Ranges
and Single Pages (all done by the coding)
However, the amount of pages i need to print out are in excess of 300 pages
When I print, the printer only seems to have enough memory for about 100 pages. I then have to start the printing again using the range of pages from say 100 on.
Alternatively in the printer set up I can set the print to print direct, This of coarse sends each page to the printer 1 at a time, which is holding up resources.
Can anyone suggest a solution so that i can print all 300 pages at the same time.
| | NoZparker Friday, September 19, 2008 11:56 AM | Private Sub PrintDocument1_BeginPrint(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintEventArgs) Handles PrintDocument1.BeginPrint
&
Private Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
To solve them simply add (double click or drag and drop)a PrintDocument to your projectfound in the toolbox
For making a Page Setup, followed by a Print Preview Dialog Box that uses your input in the Page Setup you can use this...
'Place these lines after the Public Class (Name of Form)
Public DefaultPageSettings As PageSettings = New PageSettings()
Public StringPageNo As String
Public StringNumberOfPages As String
Public BooleanNumOfPages As Boolean
Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim PageSetupDialog1 As New PageSetupDialog
PageSetupDialog1.PageSettings = DefaultPageSettings
PageSetupDialog1.ShowDialog()
Dim PrintPreviewDialog1 As New PrintPreviewDialog()
BooleanNumberOfPages = False
PrintDocument1.DefaultPageSettings = PageSetupDialog1.PageSettings
PrintPreviewDialog1.Document = PrintDocument1
PrintPreviewDialog1.ShowDialog()
End Sub
'Place theseif you a Footer (Page x of y)
If GotNumberOfPages = False Then
StringNumberOfPages = Math.Ceiling(DataGridView1.Rows.Count / RowsPerPage).ToString
GotNumberOfPages = True
End If
StringPageNo = NumberPageNumber.ToString + " of " + StringNumOfPages
Just remember that the Variables can provide an error if they won't match your project | | drill_master Monday, October 13, 2008 4:37 PM |
I want to know how I can call this code.
Call PrintDocument1_BeginPrint(sender, e)??? | | Pong Pong Monday, October 20, 2008 4:03 AM |
in any button
document1.print
in fact if you have the correct imports at the top just ouside the class declaration you should see a list
of items when you type document1 followed by a dot (document1.) | | NoZparker Friday, October 24, 2008 5:22 PM | ok the following : 1-have CoNNect fix "no print last row" 2- print only VISIBLE columns
Private oStringFormat As StringFormat Private oStringFormatComboBox As StringFormat Private oButton As Button Private oCheckbox As CheckBox Private oComboBox As ComboBox
Private nTotalWidth As Int16 Private nRowPos As Int16 Private NewPage As Boolean Private nPageNo As Int16 Private Header As String = "Header Test" Private sUserName As String = "Will"
Private Sub PrintDocument1_BeginPrint(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintEventArgs) Handles PrintDocument1.BeginPrint
oStringFormat = New StringFormat oStringFormat.Alignment = StringAlignment.Near oStringFormat.LineAlignment = StringAlignment.Center oStringFormat.Trimming = StringTrimming.EllipsisCharacter
oStringFormatComboBox = New StringFormat oStringFormatComboBox.LineAlignment = StringAlignment.Center oStringFormatComboBox.FormatFlags = StringFormatFlags.NoWrap oStringFormatComboBox.Trimming = StringTrimming.EllipsisCharacter
oButton = New Button oCheckbox = New CheckBox oComboBox = New ComboBox
nTotalWidth = 0 For Each oColumn As DataGridViewColumn In DataGridView1.Columns If oColumn.Visible = True Then nTotalWidth += oColumn.Width End If
Next nPageNo = 1 NewPage = True nRowPos = 0
End Sub
Private Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
Static oColumnLefts As New ArrayList Static oColumnWidths As New ArrayList Static oColumnTypes As New ArrayList Static nHeight As Int16
Dim nWidth, i, nRowsPerPage As Int16 Dim nTop As Int16 = e.MarginBounds.Top Dim nLeft As Int16 = e.MarginBounds.Left
If nPageNo = 1 Then
For Each oColumn As DataGridViewColumn In DataGridView1.Columns If oColumn.Visible = True Then nWidth = CType(Math.Floor(oColumn.Width / nTotalWidth * nTotalWidth * (e.MarginBounds.Width / nTotalWidth)), Int16)
nHeight = e.Graphics.MeasureString(oColumn.HeaderText, oColumn.InheritedStyle.Font, nWidth).Height + 11
oColumnLefts.Add(nLeft) oColumnWidths.Add(nWidth) oColumnTypes.Add(oColumn.GetType) nLeft += nWidth End If Next
End If
Do While nRowPos < DataGridView1.Rows.Count - 1
Dim oRow As DataGridViewRow = DataGridView1.Rows(nRowPos)
If nTop + nHeight >= e.MarginBounds.Height + e.MarginBounds.Top Then
DrawFooter(e, nRowsPerPage)
NewPage = True nPageNo += 1 e.HasMorePages = True Exit Sub
Else
If NewPage Then
' Draw Header e.Graphics.DrawString(Header, New Font(DataGridView1.Font, FontStyle.Bold), Brushes.Black, e.MarginBounds.Left, e.MarginBounds.Top - e.Graphics.MeasureString(Header, New Font(DataGridView1.Font, FontStyle.Bold), e.MarginBounds.Width).Height - 13)
' Draw Columns nTop = e.MarginBounds.Top i = 0 For Each oColumn As DataGridViewColumn In DataGridView1.Columns If oColumn.Visible = True Then e.Graphics.FillRectangle(New SolidBrush(Drawing.Color.LightGray), New Rectangle(oColumnLefts(i), nTop, oColumnWidths(i), nHeight)) e.Graphics.DrawRectangle(Pens.Black, New Rectangle(oColumnLefts(i), nTop, oColumnWidths(i), nHeight)) e.Graphics.DrawString(oColumn.HeaderText, oColumn.InheritedStyle.Font, New SolidBrush(oColumn.InheritedStyle.ForeColor), New RectangleF(oColumnLefts(i), nTop, oColumnWidths(i), nHeight), oStringFormat) i += 1 End If
Next NewPage = False
End If
nTop += nHeight i = 0 For Each oCell As DataGridViewCell In oRow.Cells If oCell.Visible = True Then If oColumnTypes(i) Is GetType(DataGridViewTextBoxColumn) OrElse oColumnTypes(i) Is GetType(DataGridViewLinkColumn) Then
e.Graphics.DrawString(oCell.Value.ToString, oCell.InheritedStyle.Font, New SolidBrush(oCell.InheritedStyle.ForeColor), New RectangleF(oColumnLefts(i), nTop, oColumnWidths(i), nHeight), oStringFormat)
ElseIf oColumnTypes(i) Is GetType(DataGridViewButtonColumn) Then
oButton.Text = oCell.Value.ToString oButton.Size = New Size(oColumnWidths(i), nHeight) Dim oBitmap As New Bitmap(oButton.Width, oButton.Height) oButton.DrawToBitmap(oBitmap, New Rectangle(0, 0, oBitmap.Width, oBitmap.Height)) e.Graphics.DrawImage(oBitmap, New Point(oColumnLefts(i), nTop))
ElseIf oColumnTypes(i) Is GetType(DataGridViewCheckBoxColumn) Then
oCheckbox.Size = New Size(14, 14) oCheckbox.Checked = CType(oCell.Value, Boolean) Dim oBitmap As New Bitmap(oColumnWidths(i), nHeight) Dim oTempGraphics As Graphics = Graphics.FromImage(oBitmap) oTempGraphics.FillRectangle(Brushes.White, New Rectangle(0, 0, oBitmap.Width, oBitmap.Height)) oCheckbox.DrawToBitmap(oBitmap, New Rectangle(CType((oBitmap.Width - oCheckbox.Width) / 2, Int32), CType((oBitmap.Height - oCheckbox.Height) / 2, Int32), oCheckbox.Width, oCheckbox.Height)) e.Graphics.DrawImage(oBitmap, New Point(oColumnLefts(i), nTop))
ElseIf oColumnTypes(i) Is GetType(DataGridViewComboBoxColumn) Then
oComboBox.Size = New Size(oColumnWidths(i), nHeight) Dim oBitmap As New Bitmap(oComboBox.Width, oComboBox.Height) oComboBox.DrawToBitmap(oBitmap, New Rectangle(0, 0, oBitmap.Width, oBitmap.Height)) e.Graphics.DrawImage(oBitmap, New Point(oColumnLefts(i), nTop)) e.Graphics.DrawString(oCell.Value.ToString, oCell.InheritedStyle.Font, New SolidBrush(oCell.InheritedStyle.ForeColor), New RectangleF(oColumnLefts(i) + 1, nTop, oColumnWidths(i) - 16, nHeight), oStringFormatComboBox)
ElseIf oColumnTypes(i) Is GetType(DataGridViewImageColumn) Then
Dim oCellSize As Rectangle = New Rectangle(oColumnLefts(i), nTop, oColumnWidths(i), nHeight) Dim oImageSize As Size = CType(oCell.Value, Image).Size e.Graphics.DrawImage(oCell.Value, New Rectangle(oColumnLefts(i) + CType(((oCellSize.Width - oImageSize.Width) / 2), Int32), nTop + CType(((oCellSize.Height - oImageSize.Height) / 2), Int32), CType(oCell.Value, Image).Width, CType(oCell.Value, Image).Height))
End If
e.Graphics.DrawRectangle(Pens.Black, New Rectangle(oColumnLefts(i), nTop, oColumnWidths(i), nHeight))
i += 1 End If Next
End If
nRowPos += 1 nRowsPerPage += 1
Loop
DrawFooter(e, nRowsPerPage)
e.HasMorePages = False
End Sub
Private Sub DrawFooter(ByVal e As System.Drawing.Printing.PrintPageEventArgs, ByVal RowsPerPage As Int32)
Dim sPageNo As String = nPageNo.ToString + " of " + Math.Ceiling(DataGridView1.Rows.Count / RowsPerPage).ToString
' Right Align - User Name e.Graphics.DrawString(sUserName, DataGridView1.Font, Brushes.Black, e.MarginBounds.Left + (e.MarginBounds.Width - e.Graphics.MeasureString(sPageNo, DataGridView1.Font, e.MarginBounds.Width).Width), e.MarginBounds.Top + e.MarginBounds.Height + 7)
' Left Align - Date/Time e.Graphics.DrawString(Now.ToLongDateString + " " + Now.ToShortTimeString, DataGridView1.Font, Brushes.Black, e.MarginBounds.Left, e.MarginBounds.Top + e.MarginBounds.Height + 7)
' Center - Page No. Info e.Graphics.DrawString(sPageNo, DataGridView1.Font, Brushes.Black, e.MarginBounds.Left + (e.MarginBounds.Width - e.Graphics.MeasureString(sPageNo, DataGridView1.Font, e.MarginBounds.Width).Width) / 2, e.MarginBounds.Top + e.MarginBounds.Height + 31)
End Sub
| | whokn0ws Monday, November 03, 2008 1:21 PM | yababer, thank you for your post, I like being able to call PrintFactory.Print() to print the dataGridView. I was having some problems with your code and have fixed them. The things that I improved were
1. Don't print columns that are not set to visible 2. Fixed the page numbers 3. Added the ability to print in Landscape
I can view the document in print preview but when I press the print button in print preview it does not print the datagridview. If anyone can fix this please let me know.
To implement create a class called PrintFactory and copy the code below into the class. To print use PrintFactory.Print(Me.DataGridView1, "Username", "Header", "L") the "L" will print in landscape, any other text string will print in portrait. Print Preview PrintFactory.Preview(Me.DataGridView1, "Username", "Header", "L")
Imports System.Windows.Forms Public Class PrintFactory #Region "Instance"
#Region "Declerations"
Private WithEvents _printDocument As Printing.PrintDocument = New Printing.PrintDocument() Private _dgv As DataGridView Private _stringFormat As StringFormat Private _stringFormatComboBox As StringFormat Private _button As Button Private _checkBox As CheckBox Private _comboBox As ComboBox Private _totalWidth As Int16 Private _rowPos As Int16 Private _newPage As Boolean Private _pageNumber As Int16 Private _userName As String Private _headerText As String Private _blnGotNumPages As Boolean Private _strNumOfPages As String Private _orientation As String
#End Region
#Region "Properties"
Private ReadOnly Property DGV() As DataGridView Get Return _dgv End Get End Property
Private Property HeaderText() As String Get Return _headerText End Get
Set(ByVal value As String) _headerText = value End Set
End Property
Private Property UserName() As String
Get Return _userName End Get
Set(ByVal value As String) _userName = value End Set End Property
Private Property StringFormat() As StringFormat Get Return _stringFormat End Get
Set(ByVal value As StringFormat) _stringFormat = value End Set End Property
Private Property StringFormatComboBox() As StringFormat Get Return _stringFormatComboBox End Get
Set(ByVal value As StringFormat) _stringFormatComboBox = value End Set End Property
Private Property Button() As Button
Get Return _button End Get
Set(ByVal value As Button) _button = value End Set End Property
Private Property CheckBox() As CheckBox Get Return _checkBox End Get
Set(ByVal value As CheckBox) _checkBox = value End Set End Property
Private Property ComboBox() As ComboBox Get Return _comboBox End Get
Set(ByVal value As ComboBox) _comboBox = value End Set End Property
Private Property TotalWidth() As Int16 Get Return _totalWidth End Get
Set(ByVal value As Int16) _totalWidth = value End Set End Property
Private Property RowPos() As Int16 Get Return _rowPos End Get
Set(ByVal value As Int16) _rowPos = value End Set End Property
Private Property NewPage() As Boolean Get Return _newPage End Get
Set(ByVal value As Boolean) _newPage = value End Set End Property
Private Property PageNumber() As Int16 Get Return _pageNumber End Get
Set(ByVal value As Int16) _pageNumber = value End Set End Property Private Property strNumOfPages() As String Get Return _strNumOfPages End Get
Set(ByVal value As String) _strNumOfPages = value End Set End Property Private Property blnGotNumPages() As Boolean Get Return _blnGotNumPages End Get
Set(ByVal value As Boolean) _blnGotNumPages = value End Set End Property Private Property orientation() As String
Get Return _orientation End Get
Set(ByVal value As String) _orientation = value End Set End Property #End Region
Private Sub New(ByVal userName As String, ByVal headerText As String) Me._userName = userName Me._headerText = headerText End Sub
Private Sub _printDocument_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles _printDocument.PrintPage EndPrint(Me, e) End Sub
#End Region
#Region "Statics"
Public Shared Function Print(ByVal dgv As DataGridView, ByVal userName As String, ByVal headerText As String, ByVal Orientation As String) As Boolean Validate(dgv, userName, headerText) Dim tempPrintFactory As PrintFactory tempPrintFactory = BeginPrint(dgv, userName, headerText) If orientation = "L" Then tempPrintFactory._printDocument.DefaultPageSettings.Landscape = True End If tempPrintFactory._printDocument.Print() End Function
Public Shared Function Preview(ByVal dgv As DataGridView, ByVal userName As String, ByVal headerText As String, ByVal Orientation As String) As Boolean Validate(dgv, userName, headerText) Dim tempPrintFactory As PrintFactory tempPrintFactory = BeginPrint(dgv, userName, headerText) If Orientation = "L" Then tempPrintFactory._printDocument.DefaultPageSettings.Landscape = True End If Dim tempPrintDiag As New PrintPreviewDialog() tempPrintDiag.Document = tempPrintFactory._printDocument tempPrintDiag.ShowDialog() End Function
Private Shared Function BeginPrint(ByVal dgv As DataGridView, ByVal userName As String, ByVal headerText As String) As PrintFactory Dim printEntity As PrintFactory = New PrintFactory(userName, headerText) printEntity._dgv = dgv printEntity.StringFormat = New StringFormat printEntity.StringFormat.Alignment = StringAlignment.Near printEntity.StringFormat.LineAlignment = StringAlignment.Center printEntity.StringFormat.Trimming = StringTrimming.EllipsisCharacter printEntity.StringFormatComboBox = New StringFormat printEntity.StringFormatComboBox.LineAlignment = StringAlignment.Center printEntity.StringFormatComboBox.FormatFlags = StringFormatFlags.NoWrap printEntity.StringFormatComboBox.Trimming = StringTrimming.EllipsisCharacter printEntity.Button = New Button printEntity.CheckBox = New CheckBox printEntity.ComboBox = New ComboBox printEntity.TotalWidth = 0
For Each oColumn As DataGridViewColumn In dgv.Columns printEntity.TotalWidth += oColumn.Width Next printEntity.PageNumber = 1 printEntity.NewPage = True printEntity.RowPos = 0 Return printEntity End Function
Private Shared Function EndPrint(ByVal printEntity As PrintFactory, ByVal e As System.Drawing.Printing.PrintPageEventArgs) As Boolean Static oColumnLefts As New ArrayList Static oColumnWidths As New ArrayList Static oColumnTypes As New ArrayList Static nHeight As Int16
Dim nWidth, i, nRowsPerPage As Int16 Dim blnGotNumPages As Boolean Dim strNumOfPages As String
Dim nTop As Int16 = e.MarginBounds.Top Dim nLeft As Int16 = e.MarginBounds.Left
If printEntity.PageNumber = 1 Then
For Each oColumn As DataGridViewColumn In printEntity.DGV.Columns If oColumn.Visible = True Then nWidth = CType(Math.Floor(oColumn.Width / printEntity.TotalWidth * printEntity.TotalWidth * (e.MarginBounds.Width / printEntity.TotalWidth)), Int16) nHeight = e.Graphics.MeasureString(oColumn.HeaderText, oColumn.InheritedStyle.Font, nWidth).Height + 11 oColumnLefts.Add(nLeft) oColumnWidths.Add(nWidth) oColumnTypes.Add(oColumn.GetType) nLeft += nWidth End If Next End If
Do While printEntity.RowPos < printEntity.DGV.Rows.Count Dim oRow As DataGridViewRow = printEntity.DGV.Rows(printEntity.RowPos)
If nTop + nHeight >= e.MarginBounds.Height + e.MarginBounds.Top Then DrawFooter(blnGotNumPages, strNumOfPages, printEntity.DGV, printEntity, nRowsPerPage, e) printEntity.NewPage = True printEntity.PageNumber += 1 e.HasMorePages = True Exit Function Else
If printEntity.NewPage Then
' Draw Header e.Graphics.DrawString(printEntity.HeaderText, New Font(printEntity.DGV.Font, FontStyle.Bold), Brushes.Black, e.MarginBounds.Left, e.MarginBounds.Top - e.Graphics.MeasureString(printEntity.HeaderText, New Font(printEntity.DGV.Font, FontStyle.Bold), e.MarginBounds.Width).Height - 13) ' Draw Columns nTop = e.MarginBounds.Top i = 0 For Each oColumn As DataGridViewColumn In printEntity.DGV.Columns
If oColumn.Visible = True Then e.Graphics.FillRectangle(New SolidBrush(Drawing.Color.LightGray), New Rectangle(oColumnLefts(i), nTop, oColumnWidths(i), nHeight)) e.Graphics.DrawRectangle(Pens.Black, New Rectangle(oColumnLefts(i), nTop, oColumnWidths(i), nHeight)) e.Graphics.DrawString(oColumn.HeaderText, oColumn.InheritedStyle.Font, New SolidBrush(oColumn.InheritedStyle.ForeColor), New RectangleF(oColumnLefts(i), nTop, oColumnWidths(i), nHeight), printEntity.StringFormat) i += 1 End If
Next
printEntity.NewPage = False End If
nTop += nHeight i = 0
For Each oCell As DataGridViewCell In oRow.Cells If oCell.Visible = True Then If oColumnTypes(i) Is GetType(DataGridViewTextBoxColumn) OrElse oColumnTypes(i) Is GetType(DataGridViewLinkColumn) Then e.Graphics.DrawString(oCell.Value.ToString, oCell.InheritedStyle.Font, New SolidBrush(oCell.InheritedStyle.ForeColor), New RectangleF(oColumnLefts(i), nTop, oColumnWidths(i), nHeight), printEntity.StringFormat) ElseIf oColumnTypes(i) Is GetType(DataGridViewButtonColumn) Then printEntity.Button.Text = oCell.Value.ToString printEntity.Button.Size = New Size(oColumnWidths(i), nHeight) Dim oBitmap As New Bitmap(printEntity.Button.Width, printEntity.Button.Height) printEntity.Button.DrawToBitmap(oBitmap, New Rectangle(0, 0, oBitmap.Width, oBitmap.Height)) e.Graphics.DrawImage(oBitmap, New Point(oColumnLefts(i), nTop)) ElseIf oColumnTypes(i) Is GetType(DataGridViewCheckBoxColumn) Then printEntity.CheckBox.Size = New Size(14, 14) printEntity.CheckBox.Checked = CType(oCell.Value, Boolean) Dim oBitmap As New Bitmap(oColumnWidths(i), nHeight) Dim oTempGraphics As Graphics = Graphics.FromImage(oBitmap) oTempGraphics.FillRectangle(Brushes.White, New Rectangle(0, 0, oBitmap.Width, oBitmap.Height)) printEntity.CheckBox.DrawToBitmap(oBitmap, New Rectangle(CType((oBitmap.Width - printEntity.CheckBox.Width) / 2, Int32), CType((oBitmap.Height - printEntity.CheckBox.Height) / 2, Int32), printEntity.CheckBox.Width, printEntity.CheckBox.Height)) e.Graphics.DrawImage(oBitmap, New Point(oColumnLefts(i), nTop)) ElseIf oColumnTypes(i) Is GetType(DataGridViewComboBoxColumn) Then printEntity.ComboBox.Size = New Size(oColumnWidths(i), nHeight) Dim oBitmap As New Bitmap(printEntity.ComboBox.Width, printEntity.ComboBox.Height) printEntity.ComboBox.DrawToBitmap(oBitmap, New Rectangle(0, 0, oBitmap.Width, oBitmap.Height)) e.Graphics.DrawImage(oBitmap, New Point(oColumnLefts(i), nTop)) e.Graphics.DrawString(oCell.Value.ToString, oCell.InheritedStyle.Font, New SolidBrush(oCell.InheritedStyle.ForeColor), New RectangleF(oColumnLefts(i) + 1, nTop, oColumnWidths(i) - 16, nHeight), printEntity.StringFormatComboBox) ElseIf oColumnTypes(i) Is GetType(DataGridViewImageColumn) Then Dim oCellSize As Rectangle = New Rectangle(oColumnLefts(i), nTop, oColumnWidths(i), nHeight) Dim oImageSize As Size = CType(oCell.Value, Image).Size
e.Graphics.DrawImage(oCell.Value, New Rectangle(oColumnLefts(i) + CType(((oCellSize.Width - oImageSize.Width) / 2), Int32), nTop + CType(((oCellSize.Height - oImageSize.Height) / 2), Int32), CType(oCell.Value, Image).Width, CType(oCell.Value, Image).Height)) End If e.Graphics.DrawRectangle(Pens.Black, New Rectangle(oColumnLefts(i), nTop, oColumnWidths(i), nHeight)) i += 1 End If Next End If
printEntity.RowPos += 1 nRowsPerPage += 1
Loop
DrawFooter(blnGotNumPages, strNumOfPages, printEntity.DGV, printEntity, nRowsPerPage, e) e.HasMorePages = False End Function Private Shared Function DrawFooter(ByVal blnGotNumPages As Boolean, ByVal strNumOfPages As String, ByVal dgv As DataGridView, ByVal printEntity As PrintFactory, ByVal RowsPerPage As Int32, ByVal e As System.Drawing.Printing.PrintPageEventArgs) As Boolean Dim sPageNo As String
If printEntity.blnGotNumPages = False Then printEntity.blnGotNumPages = True printEntity.strNumOfPages = Math.Ceiling(dgv.Rows.Count / RowsPerPage).ToString sPageNo = printEntity.PageNumber.ToString + " of " + Math.Ceiling(dgv.Rows.Count / RowsPerPage).ToString Else sPageNo = printEntity.PageNumber.ToString + " of " + printEntity.strNumOfPages End If
' Right Align - User Name e.Graphics.DrawString(printEntity.UserName, dgv.Font, Brushes.Black, e.MarginBounds.Left + (e.MarginBounds.Width - e.Graphics.MeasureString(printEntity.UserName, dgv.Font, e.MarginBounds.Width).Width), e.MarginBounds.Top + e.MarginBounds.Height + 7) ' Left Align - Date/Time e.Graphics.DrawString(Now.ToLongDateString + " " + Now.ToShortTimeString, dgv.Font, Brushes.Black, e.MarginBounds.Left, e.MarginBounds.Top + e.MarginBounds.Height + 7) ' Center - Page No. Info e.Graphics.DrawString(sPageNo, dgv.Font, Brushes.Black, e.MarginBounds.Left + (e.MarginBounds.Width - e.Graphics.MeasureString(sPageNo, dgv.Font, e.MarginBounds.Width).Width) / 2, e.MarginBounds.Top + e.MarginBounds.Height + 31) End Function
Private Shared Sub Validate(ByVal dgv As DataGridView, ByVal userName As String, ByVal headerText As String) If dgv Is Nothing Then Throw New ArgumentNullException("dgv") End If If String.IsNullOrEmpty(userName) = True Then Throw New ArgumentNullException("userName") End If If String.IsNullOrEmpty(headerText) = True Then Throw New ArgumentNullException("headerText") End If End Sub #End Region End Class - Edited byAlexWA Friday, March 20, 2009 6:04 PMFixed last row not printing
- Proposed As Answer byAlexWA Friday, March 20, 2009 6:06 PM
-
| | AlexWA Friday, March 20, 2009 6:00 PM | As I have had the same problem printing the contents of a DataGridView, I appreciate all the fine suggestions of all those who have responded to this post. However, I have the further problem of having to print not only the cell contents but the ALL the cell settings (most especially the cell background color) in my DataGridView.
Also, I need to print out the text in the RowHeader cells.
Would appreciate any help in this area.
Thanks Profusely, EdYberg | | EdYberg Friday, April 24, 2009 4:34 PM | I figured out how to print out my Row Headers and all the DGV Cell Formatting Contents using AlexWA's fine PrintFactory Class code.
Along the way I discovered that by checking the Visible property of the column, you are also checking to see whether or not your column is visible in the underlying DataGridView control which means that if you havehorizontal scrollbars showing (meaning that some columns are NOT visible due to the fact that they are not showing rather than because a user has SET then to Visible = False) those columns that are hidden by the size of the grid control will not print either. BTW, AlexWA asked why his code would not print out the first page of his grid and that is because he set the page to 1 in his BeginPrint Sub, so that by the time he gets to printing out the grid contents he is already on Page 2 and since there is no data yet for Page 2, he just prints out a blank Page 2 and he's done. Not quite sure why that happens but setting the Page to 0 in the BeginPrint Sub fixes the problem.
Thanks again to AlexWA!
(I'm sorry I can't show the code for this because I am not at my development machine right now, but if you reply to this post, I will reply with the code that I came up with.)
The problem I am now grappling with is how to print out more than 40 columns (in Landscape) by somehow capturing the total number of columns and dividing the TotalWidth by that to set the column widths... not having much success... seems that the columns just start out again at the beginning of the grid and overwrite the previous contents. - Proposed As Answer byEdYberg Saturday, May 02, 2009 11:58 AM
-
| | EdYberg Saturday, May 02, 2009 11:58 AM | Thanks a lot guys the code is amazing.. | | Ashraylavsi Wednesday, June 10, 2009 1:06 PM | Hello. Can you tell me why I'm getting in my printed paper date format like : 8.8.2009 0:00:00 ? In my datagridview there is no time at the end, but on printed paper there is. I would like to remove that time from the end, so what exactly in this code should i change to do that ? Thank you in advance. | | Boshkec Thursday, June 11, 2009 6:21 PM | Find the place in your code where it says...
' Left Align - Date/Time
e.Graphics.DrawString(Now.ToLongDateString + " " + Now.ToShortTimeString, dgv.Font, Brushes.Black, e.MarginBounds.Left, e.MarginBounds.Top + e.MarginBounds.Height + 7)
...this is the code that's printing your footer.
You could try commenting it out.
Good luck! | | EdYberg Friday, June 12, 2009 2:19 PM | EdYberg thank you for your reply and i apologize for not being clear about my problem, but i will try to explain a little better this time. I'm not having problem with time at the end (bottom) of the printed paper, but i'm having problems with time in columns that have date value . In datagridview there's correct date and there's no time after the date, but when i print it (on paper) there is time and it says "0:00:00". something like : | _____date_____ | | | | 8.8.2009 0:00:00 | | 4.4.2009 0:00:00 | | 2.6.2009 0:00:00 | Also in access table that column i set to short date and there's just date (no time). My English is not very good but i hope i explained myself a little better this time. Any kind of help will be very appreciated.
| | Boshkec Saturday, June 13, 2009 1:47 PM | Hi Will-affinity
your code works great but the document is being printed on the right of the page and no footer, this hapends on a DGV that is bindet by code, if i use a DGV and Bind it by smart tag it works fine. is there a fix for this>
If i can make the default layout to Landscape that will do
thanks - Edited bydeti Friday, July 03, 2009 9:01 PM
-
| | deti Friday, July 03, 2009 3:55 PM | Thanks so much for this routine. I was printing pages on top of each other and about to pull my hair out. This routine you posted works great, even better than I expected with very little work needed to insert into my project. I realize it is three years old but it still works great in VBE2008 | | wheezerjoe Sunday, July 26, 2009 11:15 PM | hi there, i'm new here.. i've tried your codes and it's great but i want to print something on the last page like "NOTHING FOLLOWS", i really dont know where to put the DrawString thing here.. all i want to to do is to print something on the last page.. could you help me??
| | thesoulballadeer Monday, August 03, 2009 1:40 PM | hi there Nectuss.. that's great i have tried it, and my printing now is working properly, the last record on the DataGridView is now recognized.. and the records don't overlap with the footer.. btw, can you help with the printing of text or string on the last page of the reports.. i just dont know where to put the draw string thing, i want to some text like "NOTHING FOLLOWS".. on the last part of the page.. plz help me.. im hoping for your response.. | | thesoulballadeer Monday, August 03, 2009 1:43 PM | [i][i][i][i] | | Gnoelwoes Sunday, August 09, 2009 11:27 AM | hi there, im new here, i want to know how to print some string after the datagridview contents, like i want to print the "NOTHING FOLLOWS", or even "Total Nos. of Records", something like that, i want to know how to, pls help me guyz.. | | thesoulballadeer Monday, August 17, 2009 2:45 PM | hi there, i wanted to know how to print some label or string after printing the contents of the datagridview, like for example i wanted to print the total no. of records in the datagridview table that has been printed or like i wanted to print "NOTHING FOLLOWS" after the printing of the records, i wanted to place them after the last record that was printed, ive been working on it lately but it seems that i really cant do it, could you help me out here? | | thesoulballadeer Monday, August 17, 2009 2:49 PM | hi there, i wanted to know how to print some label or string after printing the contents of the datagridview, like for example i wanted to print the total no. of records in the datagridview table that has been printed or like i wanted to print "NOTHING FOLLOWS" after the printing of the records, i wanted to place them after the last record that was printed, ive been working on it lately but it seems that i really cant do it, could you help me out here? | | thesoulballadeer Monday, August 17, 2009 2:50 PM | Private oStringFormat As StringFormat Private oStringFormatComboBox As StringFormat Private oButton As Button Private oCheckbox As CheckBox Private oComboBox As ComboBox
Private nTotalWidth As Int16 Private nRowPos As Int16 Private NewPage As Boolean Private nPageNo As Int16 Private Header As String = "Header Test" Private sUserName As String = "Will"
Private Sub PrintDocument1_BeginPrint(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintEventArgs) Handles PrintDocument1.BeginPrint
oStringFormat = New StringFormat oStringFormat.Alignment = StringAlignment.Near oStringFormat.LineAlignment = StringAlignment.Center oStringFormat.Trimming = StringTrimming.EllipsisCharacter
oStringFormatComboBox = New StringFormat oStringFormatComboBox.LineAlignment = StringAlignment.Center oStringFormatComboBox.FormatFlags = StringFormatFlags.NoWrap oStringFormatComboBox.Trimming = StringTrimming.EllipsisCharacter
oButton = New Button oCheckbox = New CheckBox oComboBox = New ComboBox
nTotalWidth = 0 For Each oColumn As DataGridViewColumn In DataGridView1.Columns
nTotalWidth += oColumn.Width
Next nPageNo = 1 NewPage = True nRowPos = 0
End Sub
Private Sub PrintDocument1_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDocument1.PrintPage
Static oColumnLefts As New ArrayList Static oColumnWidths As New ArrayList Static oColumnTypes As New ArrayList Static nHeight As Int16
Dim nWidth, i, nRowsPerPage As Int16 Dim nTop As Int16 = e.MarginBounds.Top Dim nLeft As Int16 = e.MarginBounds.Left
If nPageNo = 1 Then
For Each oColumn As DataGridViewColumn In DataGridView1.Columns
nWidth = CType(Math.Floor(oColumn.Width / nTotalWidth * nTotalWidth * (e.MarginBounds.Width / nTotalWidth)), Int16)
nHeight = e.Graphics.MeasureString(oColumn.HeaderText, oColumn.InheritedStyle.Font, nWidth).Height + 11
oColumnLefts.Add(nLeft) oColumnWidths.Add(nWidth) oColumnTypes.add(oColumn.GetType) nLeft += nWidth
Next
End If
Do While nRowPos < DataGridView1.Rows.Count - 1
Dim oRow As DataGridViewRow = DataGridView1.Rows(nRowPos)
If nTop + nHeight >= e.MarginBounds.Height + e.MarginBounds.Top Then
DrawFooter(e, nRowsPerPage)
NewPage = True nPageNo += 1 e.HasMorePages = True Exit Sub
Else
If NewPage Then
' Draw Header e.Graphics.DrawString(Header, New Font(DataGridView1.Font, FontStyle.Bold), Brushes.Black, e.MarginBounds.Left, e.MarginBounds.Top - e.Graphics.MeasureString(Header, New Font(DataGridView1.Font, FontStyle.Bold), e.MarginBounds.Width).Height - 13)
' Draw Columns nTop = e.MarginBounds.Top i = 0 For Each oColumn As DataGridViewColumn In DataGridView1.Columns
e.Graphics.FillRectangle(New SolidBrush(Drawing.Color.LightGray), New Rectangle(oColumnLefts(i), nTop, oColumnWidths(i), nHeight)) e.Graphics.DrawRectangle(Pens.Black, New Rectangle(oColumnLefts(i), nTop, oColumnWidths(i), nHeight)) e.Graphics.DrawString(oColumn.HeaderText, oColumn.InheritedStyle.Font, New SolidBrush(oColumn.InheritedStyle.ForeColor), New RectangleF(oColumnLefts(i), nTop, oColumnWidths(i), nHeight), oStringFormat) i += 1
Next NewPage = False
End If
nTop += nHeight i = 0 For Each oCell As DataGridViewCell In oRow.Cells
If oColumnTypes(i) Is GetType(DataGridViewTextBoxColumn) OrElse oColumnTypes(i) Is GetType(DataGridViewLinkColumn) Then
e.Graphics.DrawString(oCell.Value.ToString, oCell.InheritedStyle.Font, New SolidBrush(oCell.InheritedStyle.ForeColor), New RectangleF(oColumnLefts(i), nTop, oColumnWidths(i), nHeight), oStringFormat)
ElseIf oColumnTypes(i) Is GetType(DataGridViewButtonColumn) Then
oButton.Text = oCell.Value.ToString oButton.Size = New Size(oColumnWidths(i), nHeight) Dim oBitmap As New Bitmap(oButton.Width, oButton.Height) oButton.DrawToBitmap(oBitmap, New Rectangle(0, 0, oBitmap.Width, oBitmap.Height)) e.Graphics.DrawImage(oBitmap, New Point(oColumnLefts(i), nTop))
ElseIf oColumnTypes(i) Is GetType(DataGridViewCheckBoxColumn) Then
oCheckbox.Size = New Size(14, 14) oCheckbox.Checked = CType(oCell.Value, Boolean) Dim oBitmap As New Bitmap(oColumnWidths(i), nHeight) Dim oTempGraphics As Graphics = Graphics.FromImage(oBitmap) oTempGraphics.FillRectangle(Brushes.White, New Rectangle(0, 0, oBitmap.Width, oBitmap.Height)) oCheckbox.DrawToBitmap(oBitmap, New Rectangle(CType((oBitmap.Width - oCheckbox.Width) / 2, Int32), CType((oBitmap.Height - oCheckbox.Height) / 2, Int32), oCheckbox.Width, oCheckbox.Height)) e.Graphics.DrawImage(oBitmap, New Point(oColumnLefts(i), nTop))
ElseIf oColumnTypes(i) Is GetType(DataGridViewComboBoxColumn) Then
oComboBox.Size = New Size(oColumnWidths(i), nHeight) Dim oBitmap As New Bitmap(oComboBox.Width, oComboBox.Height) oComboBox.DrawToBitmap(oBitmap, New Rectangle(0, 0, oBitmap.Width, oBitmap.Height)) e.Graphics.DrawImage(oBitmap, New Point(oColumnLefts(i), nTop)) e.Graphics.DrawString(oCell.Value.ToString, oCell.InheritedStyle.Font, New SolidBrush(oCell.InheritedStyle.ForeColor), New RectangleF(oColumnLefts(i) + 1, nTop, oColumnWidths(i) - 16, nHeight), oStringFormatComboBox)
ElseIf oColumnTypes(i) Is GetType(DataGridViewImageColumn) Then
Dim oCellSize As Rectangle = New Rectangle(oColumnLefts(i), nTop, oColumnWidths(i), nHeight) Dim oImageSize As Size = CType(oCell.Value, Image).Size e.Graphics.DrawImage(oCell.Value, New Rectangle(oColumnLefts(i) + CType(((oCellSize.Width - oImageSize.Width) / 2), Int32), nTop + CType(((oCellSize.Height - oImageSize.Height) / 2), Int32), CType(oCell.Value, Image).Width, CType(oCell.Value, Image).Height))
End If
e.Graphics.DrawRectangle(Pens.Black, New Rectangle(oColumnLefts(i), nTop, oColumnWidths(i), nHeight))
i += 1
Next
End If
nRowPos += 1 nRowsPerPage += 1
Loop
DrawFooter(e, nRowsPerPage)
e.HasMorePages = False
End Sub
Private Sub DrawFooter(ByVal e As System.Drawing.Printing.PrintPageEventArgs, ByVal RowsPerPage As Int32)
Dim sPageNo As String = nPageNo.ToString + " of " + Math.Ceiling(DataGridView1.Rows.Count / RowsPerPage).ToString
' Right Align - User Name e.Graphics.DrawString(sUserName, DataGridView1.Font, Brushes.Black, e.MarginBounds.Left + (e.MarginBounds.Width - e.Graphics.MeasureString(sPageNo, DataGridView1.Font, e.MarginBounds.Width).Width), e.MarginBounds.Top + e.MarginBounds.Height + 7)
' Left Align - Date/Time e.Graphics.DrawString(Now.ToLongDateString + " " + Now.ToShortTimeString, DataGridView1.Font, Brushes.Black, e.MarginBounds.Left, e.MarginBounds.Top + e.MarginBounds.Height + 7)
' Center - Page No. Info e.Graphics.DrawString(sPageNo, DataGridView1.Font, Brushes.Black, e.MarginBounds.Left + (e.MarginBounds.Width - e.Graphics.MeasureString(sPageNo, DataGridView1.Font, e.MarginBounds.Width).Width) / 2, e.MarginBounds.Top + e.MarginBounds.Height + 31)
End Sub
hi there, i wanted to know how to print some label or string after printing the contents of the datagridview, like for example i wanted to print the total no. of records in the datagridview table that has been printed or like i wanted to print "NOTHING FOLLOWS" after the printing of the records, i wanted to place them after the last record that was printed, ive been working on it lately but it seems that i really cant do it, could you help me out here? | | thesoulballadeer Monday, August 17, 2009 2:50 PM | There's a problem with printing out the footer. It messes up the page number if the page has fewer than the max number of rows. For example, I had 38 rows spread over two pages, the first page said "Page 1 of 2" but the last one would say "Page 2 of 13" since there were only 3 rows on the final page. Either way, I've 'Option Stricted' and turned it into a class unto itself. Enjoy! To Implement: Private Sub btnPrintPreview_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPrintPreview.Click If IsNothing(Printer) Then Printer = New Printer(dgvJobs, Me.Text, gblUserName) 'DataGridView, Wiindow Title (as the Page Header), Username End If Printer.ShowPrintPreviewDialog() End Sub Private Sub btnPrint_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPrint.Click If IsNothing(Printer) Then Printer = New Printer(dgvJobs, Me.Text, gblUserName) 'DataGridView, Wiindow Title (as the Page Header), Username End If Printer.Print() End Sub Public Class Printer Private oStringFormat As StringFormat Private oStringFormatComboBox As StringFormat Private oButton As Button Private oCheckbox As CheckBox Private oComboBox As ComboBox Private nTotalWidth As Int16 Private nRowPos As Int16 Private NewPage As Boolean Private nPageNo As Int16 Private Header As String Private sUserName As String Private nPageCount As Integer = 0 Private dgv As DataGridView Private WithEvents PrintDoc As New Printing.PrintDocument Private storedPageSettings As Printing.PageSettings = New Printing.PageSettings() Property DataGridViewToPrint() As DataGridView Get Return dgv End Get Set(ByVal value As DataGridView) dgv = value End Set End Property Property UserName() As String Get Return sUserName End Get Set(ByVal value As String) sUserName = value End Set End Property Property HeaderText() As String Get Return Header End Get Set(ByVal value As String) Header = value End Set End Property Public Sub New(ByVal aDGV As DataGridView, ByVal aHeader As String, ByVal aUserName As String) DataGridViewToPrint = aDGV UserName = aUserName HeaderText = aHeader End Sub Public Sub Print() Dim psDlg As New PageSetupDialog psDlg.PageSettings = storedPageSettings psDlg.ShowDialog() End Sub Public Sub ShowPrintPreviewDialog() Dim dlg As New PrintPreviewDialog() dlg.Document = PrintDoc dlg.ShowDialog() End Sub Private Sub PrintDoc_BeginPrint(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintEventArgs) Handles PrintDoc.BeginPrint oStringFormat = New StringFormat oStringFormat.Alignment = StringAlignment.Near oStringFormat.LineAlignment = StringAlignment.Center oStringFormat.Trimming = StringTrimming.EllipsisCharacter oStringFormatComboBox = New StringFormat oStringFormatComboBox.LineAlignment = StringAlignment.Center oStringFormatComboBox.FormatFlags = StringFormatFlags.NoWrap oStringFormatComboBox.Trimming = StringTrimming.EllipsisCharacter oButton = New Button oCheckbox = New CheckBox oComboBox = New ComboBox nTotalWidth = 0 For Each oColumn As DataGridViewColumn In DataGridViewToPrint.Columns nTotalWidth = CShort(nTotalWidth + oColumn.Width) Next nPageNo = 1 NewPage = True nRowPos = 0 End Sub Private Sub Printdoc_PrintPage(ByVal sender As Object, ByVal e As System.Drawing.Printing.PrintPageEventArgs) Handles PrintDoc.PrintPage Static oColumnLefts As New ArrayList Static oColumnWidths As New ArrayList Static oColumnTypes As New ArrayList Static nHeight As Int16 Dim nWidth, i, nRowsPerPage As Int16 Dim nTop As Int16 = CShort(e.MarginBounds.Top) Dim nLeft As Int16 = CShort(e.MarginBounds.Left) If nPageNo = 1 Then For Each oColumn As DataGridViewColumn In DataGridViewToPrint.Columns nWidth = CType(Math.Floor(oColumn.Width / nTotalWidth * nTotalWidth * (e.MarginBounds.Width / nTotalWidth)), Int16) nHeight = CShort(e.Graphics.MeasureString(oColumn.HeaderText, oColumn.InheritedStyle.Font, nWidth).Height + 11) oColumnLefts.Add(nLeft) oColumnWidths.Add(nWidth) oColumnTypes.Add(oColumn.GetType) nLeft += nWidth Next End If Do While nRowPos < DataGridViewToPrint.Rows.Count Dim oRow As DataGridViewRow = DataGridViewToPrint.Rows(nRowPos) If nTop + nHeight >= e.MarginBounds.Height + e.MarginBounds.Top Then DrawFooter(e, nRowsPerPage) NewPage = True nPageNo = CShort(nPageNo + 1) e.HasMorePages = True Exit Sub Else If NewPage Then ' Draw Header e.Graphics.DrawString(Header, New Font(DataGridViewToPrint.Font, FontStyle.Bold), Brushes.Black, e.MarginBounds.Left, e.MarginBounds.Top - e.Graphics.MeasureString(Header, New Font(DataGridViewToPrint.Font, FontStyle.Bold), e.MarginBounds.Width).Height - 13) ' Draw Columns nTop = CShort(e.MarginBounds.Top) i = 0 For Each oColumn As DataGridViewColumn In DataGridViewToPrint.Columns e.Graphics.FillRectangle(New SolidBrush(Drawing.Color.LightGray), New Rectangle(CInt(oColumnLefts(i)), nTop, CInt(oColumnWidths(i)), nHeight)) e.Graphics.DrawRectangle(Pens.Black, New Rectangle(CInt(oColumnLefts(i)), nTop, CInt(oColumnWidths(i)), nHeight)) e.Graphics.DrawString(oColumn.HeaderText, oColumn.InheritedStyle.Font, New SolidBrush(oColumn.InheritedStyle.ForeColor), New RectangleF(CSng(oColumnLefts(i)), nTop, CSng(oColumnWidths(i)), nHeight), oStringFormat) i = CShort(i + 1) Next NewPage = False End If nTop += nHeight i = 0 For Each oCell As DataGridViewCell In oRow.Cells If oColumnTypes(i) Is GetType(DataGridViewTextBoxColumn) OrElse oColumnTypes(i) Is GetType(DataGridViewLinkColumn) Then e.Graphics.DrawString(oCell.Value.ToString, oCell.InheritedStyle.Font, New SolidBrush(oCell.InheritedStyle.ForeColor), New RectangleF(CSng(oColumnLefts(i)), nTop, CSng(oColumnWidths(i)), nHeight), oStringFormat) ElseIf oColumnTypes(i) Is GetType(DataGridViewButtonColumn) Then oButton.Text = oCell.Value.ToString oButton.Size = New Size(CInt(oColumnWidths(i)), nHeight) Dim oBitmap As New Bitmap(oButton.Width, oButton.Height) oButton.DrawToBitmap(oBitmap, New Rectangle(0, 0, oBitmap.Width, oBitmap.Height)) e.Graphics.DrawImage(oBitmap, New Point(CInt(oColumnLefts(i)), nTop)) ElseIf oColumnTypes(i) Is GetType(DataGridViewCheckBoxColumn) Then oCheckbox.Size = New Size(14, 14) oCheckbox.Checked = CType(oCell.Value, Boolean) Dim oBitmap As New Bitmap(CInt(oColumnWidths(i)), nHeight) Dim oTempGraphics As Graphics = Graphics.FromImage(oBitmap) oTempGraphics.FillRectangle(Brushes.White, New Rectangle(0, 0, oBitmap.Width, oBitmap.Height)) oCheckbox.DrawToBitmap(oBitmap, New Rectangle(CType((oBitmap.Width - oCheckbox.Width) / 2, Int32), CType((oBitmap.Height - oCheckbox.Height) / 2, Int32), oCheckbox.Width, oCheckbox.Height)) e.Graphics.DrawImage(oBitmap, New Point(CInt(oColumnLefts(i)), nTop)) ElseIf oColumnTypes(i) Is GetType(DataGridViewComboBoxColumn) Then oComboBox.Size = New Size(CInt(oColumnWidths(i)), nHeight) Dim oBitmap As New Bitmap(oComboBox.Width, oComboBox.Height) oComboBox.DrawToBitmap(oBitmap, New Rectangle(0, 0, oBitmap.Width, oBitmap.Height)) e.Graphics.DrawImage(oBitmap, New Point(CInt(oColumnLefts(i)), nTop)) e.Graphics.DrawString(oCell.Value.ToString, oCell.InheritedStyle.Font, New SolidBrush(oCell.InheritedStyle.ForeColor), New RectangleF(CInt(oColumnLefts(i)) + 1, nTop, CInt(oColumnWidths(i)) - 16, nHeight), oStringFormatComboBox) ElseIf oColumnTypes(i) Is GetType(DataGridViewImageColumn) Then Dim oCellSize As Rectangle = New Rectangle(CInt(oColumnLefts(i)), nTop, CInt(oColumnWidths(i)), nHeight) Dim oImageSize As Size = CType(oCell.Value, Image).Size e.Graphics.DrawImage(CType(oCell.Value, Image), New Rectangle(CType(oColumnLefts(i), Int32) + CType(((oCellSize.Width - oImageSize.Width) / 2), Int32), nTop + CType(((oCellSize.Height - oImageSize.Height) / 2), Int32), CType(oCell.Value, Image).Width, CType(oCell.Value, Image).Height)) End If e.Graphics.DrawRectangle(Pens.Black, New Rectangle(CInt(oColumnLefts(i)), nTop, CInt(oColumnWidths(i)), nHeight)) i = CShort(i + 1) Next End If nRowPos = CShort(nRowPos + 1) nRowsPerPage = CShort(nRowsPerPage + 1) Loop DrawFooter(e, nRowsPerPage) e.HasMorePages = False End Sub Private Sub DrawFooter(ByVal e As System.Drawing.Printing.PrintPageEventArgs, ByVal RowsPerPage As Int32) 'Changed from Page XXX of XXX to just Page XXX because 'Math.Ceiling(DataGridViewToPrint.Rows.Count / RowsPerPage).ToString() would generate 'inaccurate page numbers on pages with less than the max number of rows (ie: the last page) 'Dim sPageNo As String = nPageNo.ToString + " of " + Math.Ceiling(DataGridViewToPrint.Rows.Count / RowsPerPage).ToString Dim sPageNo As String = "Page " + nPageNo.ToString ' Right Align - User Name e.Graphics.DrawString("Printed by: " + sUserName, DataGridViewToPrint.Font, Brushes.Black, e.MarginBounds.Left + (e.MarginBounds.Width - e.Graphics.MeasureString(sPageNo, DataGridViewToPrint.Font, e.MarginBounds.Width).Width), e.MarginBounds.Top + e.MarginBounds.Height + 7) ' Left Align - Date/Time e.Graphics.DrawString(Now.ToLongDateString + " " + Now.ToShortTimeString, DataGridViewToPrint.Font, Brushes.Black, e.MarginBounds.Left, e.MarginBounds.Top + e.MarginBounds.Height + 7) ' Center - Page No. Info e.Graphics.DrawString(sPageNo, DataGridViewToPrint.Font, Brushes.Black, e.MarginBounds.Left + (e.MarginBounds.Width - e.Graphics.MeasureString(sPageNo, DataGridViewToPrint.Font, e.MarginBounds.Width).Width) / 2, e.MarginBounds.Top + e.MarginBounds.Height + 31) End Sub End Class
hi there, i wanted to know how to print some label or string after printing the contents of the datagridview, like for example i wanted to print the total no. of records in the datagridview table that has been printed or like i wanted to print "NOTHING FOLLOWS" after the printing of the records, i wanted to place them after the last record that was printed, ive been working on it lately but it seems that i really cant do it, could you help me out here? | | thesoulballadeer Monday, August 17, 2009 2:51 PM | Hi, This code is absolutely amazing. works exactly the way I want... However, I have a question: Can a particular cell be aligned Right ? I looked in the code but could not find any way to alter the default alignment. Any help in this regard would be appreciated. Thanks Kazmi | | sbakazmi Tuesday, August 25, 2009 10:54 PM |
|