1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174
| public class PrintGridDocument : PrintDocument
{
//Data Members
private DataGrid m_oDataGrid;
private int m_nCurrPage;
private int m_nCurrRow;
private int m_nColumns;
private int m_nRows;
private bool m_bInitialized;
private int m_nLinesPerPage;
private int m_nTotalPages;
private int[] m_nColBounds;
//Properties
public Font PrintFont;
public string Title;
public PrintGridDocument(DataGrid aGrid) : base()
{
//Default Values
m_oDataGrid = aGrid;
m_nCurrPage = 0;
m_nCurrRow = 0;
m_bInitialized = false;
//Get total number of cols/rows in the data source
m_nColumns = ((DataTable)(m_oDataGrid.DataSource)).Columns.Count;
m_nRows = ((DataTable)(m_oDataGrid.DataSource)).Rows.Count;
}
//Override OnBeginPrint to set up the font we are going to use
protected override void OnBeginPrint(PrintEventArgs ev)
{
base.OnBeginPrint(ev);
//If client has not created a font, create a default font
// Note: an exception could be raised here, but it is deliberately not
// being caught because there is nothing we could do at this point!
if(PrintFont == null)
PrintFont = new Font("Arial", 9);
}
//Override the OnPrintPage to provide the printing logic for the document
protected override void OnPrintPage(PrintPageEventArgs e)
{
//Call base method
base.OnPrintPage(e);
//Get the margins
int nTextPosX = e.MarginBounds.Left;
int nTextPosY = e.MarginBounds.Top;
//Do first time initialization stuff
if(!m_bInitialized)
{
// Calculate the number of lines per page.
m_nLinesPerPage = (int)(e.MarginBounds.Height / PrintFont.GetHeight(e.Graphics));
m_nTotalPages = (int)Math.Ceiling((float)m_nRows / (float)m_nLinesPerPage);
//Create bounding box for columns
m_nColBounds = new int[m_nColumns];
//Calculate the correct spacing for the columns
for(int nCol = 0;nCol<m_nColumns;nCol++)
{
//Measure the column headers first
m_nColBounds[nCol] = (int)e.Graphics.MeasureString(
((DataTable)(m_oDataGrid.DataSource)).Columns[nCol].ColumnName, PrintFont).Width;
for(int nRow=0;nRow<m_nRows;nRow++)
{
//Compare data to current max
if(e.Graphics.MeasureString(m_oDataGrid[nRow,nCol].ToString(),PrintFont).Width > m_nColBounds[nCol])
m_nColBounds[nCol] = (int)e.Graphics.MeasureString(m_oDataGrid[nRow,nCol].ToString(),PrintFont).Width;
}
//Just use max possible size if too large
if(m_nColBounds[nCol] > e.MarginBounds.Width / m_nColumns)
m_nColBounds[nCol] = e.MarginBounds.Width / m_nColumns;
//Can't be less than column width
if(m_nColBounds[nCol] < (int)Math.Round(e.Graphics.MeasureString(((DataTable)(m_oDataGrid.DataSource)).Columns[nCol].ColumnName, PrintFont).Width))
m_nColBounds[nCol] = (int)Math.Round(e.Graphics.MeasureString(((DataTable)(m_oDataGrid.DataSource)).Columns[nCol].ColumnName, PrintFont).Width);
}
//Move to correct starting page
if(this.PrinterSettings.PrintRange == PrintRange.SomePages)
{
while(m_nCurrPage < this.PrinterSettings.FromPage-1)
{
//Move to next page - advance data to next page as well
m_nCurrRow += m_nLinesPerPage;
m_nCurrPage++;
if(m_nCurrRow > m_nRows)
return;
}
if(m_nCurrPage > this.PrinterSettings.ToPage)
{
//Don't print anything more
return;
}
}
//Set flag
m_bInitialized = true;
}
//Move to next page
m_nCurrPage++;
//Print Title if first page
if(m_nCurrPage == 1)
{
Font TitleFont = new Font("Arial",15);
int nXPos = (int)(((e.PageBounds.Right - e.PageBounds.Left) /2 ) -
(e.Graphics.MeasureString(Title,TitleFont).Width / 2));
e.Graphics.DrawString(Title,TitleFont,Brushes.Black,nXPos,e.MarginBounds.Top - TitleFont.GetHeight(e.Graphics) - 10);
}
//Draw page number
string strOutput = "Page " + m_nCurrPage + " of " + m_nTotalPages;
e.Graphics.DrawString(strOutput,PrintFont,Brushes.Black,e.MarginBounds.Right - e.Graphics.MeasureString(strOutput,PrintFont).Width,
e.MarginBounds.Bottom);
//Utility rectangle - use for many drawing operations
Rectangle aRect = new Rectangle();
//Loop through data
for(int nRow=m_nCurrRow; nRow < m_nRows; nRow++)
{
//Draw the current row within a shaded/unshaded box
aRect.X = e.MarginBounds.Left;
aRect.Y = nTextPosY;
aRect.Width = e.MarginBounds.Width;
aRect.Height = (int)PrintFont.GetHeight(e.Graphics);
//Draw the box
if(nRow%2 == 0)
e.Graphics.FillRectangle(Brushes.LightGray,aRect);
e.Graphics.DrawRectangle(Pens.Black,aRect);
//Loop through each column
for(int nCol=0; nCol < m_nColumns; nCol++)
{
//Set the rectangle to the correct position
aRect.X = nTextPosX;
aRect.Y = nTextPosY;
aRect.Width = m_nColBounds[nCol];
aRect.Height = (int)PrintFont.GetHeight(e.Graphics);
//Print the data
e.Graphics.DrawString(m_oDataGrid[nRow,nCol].ToString(),PrintFont,Brushes.Black,aRect);
//Advance the x Position counter
nTextPosX += m_nColBounds[nCol];
}
//Reassign the x position counter
nTextPosX = e.MarginBounds.Left;
//Move the y position counter down a line
nTextPosY += (int)PrintFont.GetHeight(e.Graphics);
//Check to see if we have reached the line limit - move to a new page if so
if(nRow - ((m_nCurrPage-1) * m_nLinesPerPage) == m_nLinesPerPage)
{
//Save the current row
m_nCurrRow = ++nRow;
e.HasMorePages = true;
return;
}
}
}
} |
Partager