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
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
| // Calculating the starting x coordinate that the printing process will start from
float CurrentX = (float)LeftMargin;
if (IsCenterOnPage)
CurrentX += (((float)PageWidth - (float)RightMargin - (float)LeftMargin) - mColumnPointsWidth[mColumnPoint]) / 2.0F;
// Setting the HeaderFore style
Color HeaderForeColor = TheDataGridView.ColumnHeadersDefaultCellStyle.ForeColor;
if (HeaderForeColor.IsEmpty) // If there is no special HeaderFore style, then use the default DataGridView style
HeaderForeColor = TheDataGridView.DefaultCellStyle.ForeColor;
SolidBrush HeaderForeBrush = new SolidBrush(HeaderForeColor);
// Setting the HeaderBack style
Color HeaderBackColor = TheDataGridView.ColumnHeadersDefaultCellStyle.BackColor;
if (HeaderBackColor.IsEmpty) // If there is no special HeaderBack style, then use the default DataGridView style
HeaderBackColor = TheDataGridView.DefaultCellStyle.BackColor;
SolidBrush HeaderBackBrush = new SolidBrush(HeaderBackColor);
// Setting the LinePen that will be used to draw lines and rectangles (derived from the GridColor property of the DataGridView control)
Pen TheLinePen = new Pen(TheDataGridView.GridColor, 1);
// Setting the HeaderFont style
Font HeaderFont = TheDataGridView.ColumnHeadersDefaultCellStyle.Font;
if (HeaderFont == null) // If there is no special HeaderFont style, then use the default DataGridView font style
HeaderFont = TheDataGridView.DefaultCellStyle.Font;
// Calculating and drawing the HeaderBounds
RectangleF HeaderBounds = new RectangleF(CurrentX, CurrentY, mColumnPointsWidth[mColumnPoint], RowHeaderHeight);
g.FillRectangle(HeaderBackBrush, HeaderBounds);
// Setting the format that will be used to print each cell of the header row
StringFormat CellFormat = new StringFormat();
CellFormat.Trimming = StringTrimming.Word;
CellFormat.FormatFlags = StringFormatFlags.NoWrap | StringFormatFlags.LineLimit | StringFormatFlags.NoClip;
// Printing each visible cell of the header row
RectangleF CellBounds;
float ColumnWidth;
for (int i = (int)mColumnPoints[mColumnPoint].GetValue(0); i < (int)mColumnPoints[mColumnPoint].GetValue(1); i++)
{
if (!TheDataGridView.Columns[i].Visible) continue; // If the column is not visible then ignore this iteration
ColumnWidth = ColumnsWidth[i];
// Check the CurrentCell alignment and apply it to the CellFormat
if (TheDataGridView.ColumnHeadersDefaultCellStyle.Alignment.ToString().Contains("Right"))
CellFormat.Alignment = StringAlignment.Far;
else if (TheDataGridView.ColumnHeadersDefaultCellStyle.Alignment.ToString().Contains("Center"))
CellFormat.Alignment = StringAlignment.Center;
else
CellFormat.Alignment = StringAlignment.Near;
CellBounds = new RectangleF(CurrentX, CurrentY, ColumnWidth, RowHeaderHeight);
// Printing the cell text
g.DrawString(TheDataGridView.Columns[i].HeaderText, HeaderFont, HeaderForeBrush, CellBounds, CellFormat);
// Drawing the cell bounds
if (TheDataGridView.RowHeadersBorderStyle != DataGridViewHeaderBorderStyle.None) // Draw the cell border only if the HeaderBorderStyle is not None
g.DrawRectangle(TheLinePen, CurrentX, CurrentY, ColumnWidth, RowHeaderHeight);
CurrentX += ColumnWidth;
}
CurrentY += RowHeaderHeight;
/////////
//////////////////
}
// The function that print a bunch of rows that fit in one page
// When it returns true, meaning that there are more rows still not printed, so another PagePrint action is required
// When it returns false, meaning that all rows are printed (the CureentRow parameter reaches the last row of the DataGridView control) and no further PagePrint action is required
private bool DrawRows(Graphics g)
{
// Setting the LinePen that will be used to draw lines and rectangles (derived from the GridColor property of the DataGridView control)
Pen TheLinePen = new Pen(TheDataGridView.GridColor, 1);
// The style paramters that will be used to print each cell
Font RowFont;
Color RowForeColor;
Color RowBackColor;
SolidBrush RowForeBrush;
SolidBrush RowBackBrush;
SolidBrush RowAlternatingBackBrush;
// Setting the format that will be used to print each cell
StringFormat CellFormat = new StringFormat();
CellFormat.Trimming = StringTrimming.Word;
CellFormat.FormatFlags = StringFormatFlags.NoWrap | StringFormatFlags.LineLimit;
// Printing each visible cell
RectangleF RowBounds;
float CurrentX;
float ColumnWidth;
while (CurrentRow < TheDataGridView.Rows.Count)
{
if (TheDataGridView.Rows[CurrentRow].Visible) // Print the cells of the CurrentRow only if that row is visible
{
// Setting the row font style
RowFont = TheDataGridView.Rows[CurrentRow].DefaultCellStyle.Font;
if (RowFont == null) // If the there is no special font style of the CurrentRow, then use the default one associated with the DataGridView control
RowFont = TheDataGridView.DefaultCellStyle.Font;
// Setting the RowFore style
RowForeColor = TheDataGridView.Rows[CurrentRow].DefaultCellStyle.ForeColor;
if (RowForeColor.IsEmpty) // If the there is no special RowFore style of the CurrentRow, then use the default one associated with the DataGridView control
RowForeColor = TheDataGridView.DefaultCellStyle.ForeColor;
RowForeBrush = new SolidBrush(RowForeColor);
// Setting the RowBack (for even rows) and the RowAlternatingBack (for odd rows) styles
RowBackColor = TheDataGridView.Rows[CurrentRow].DefaultCellStyle.BackColor;
if (RowBackColor.IsEmpty) // If the there is no special RowBack style of the CurrentRow, then use the default one associated with the DataGridView control
{
RowBackBrush = new SolidBrush(TheDataGridView.DefaultCellStyle.BackColor);
RowAlternatingBackBrush = new SolidBrush(TheDataGridView.AlternatingRowsDefaultCellStyle.BackColor);
}
else // If the there is a special RowBack style of the CurrentRow, then use it for both the RowBack and the RowAlternatingBack styles
{
RowBackBrush = new SolidBrush(RowBackColor);
RowAlternatingBackBrush = new SolidBrush(RowBackColor);
}
// Calculating the starting x coordinate that the printing process will start from
CurrentX = (float)LeftMargin;
if (IsCenterOnPage)
CurrentX += (((float)PageWidth - (float)RightMargin - (float)LeftMargin) - mColumnPointsWidth[mColumnPoint]) / 2.0F;
// Calculating the entire CurrentRow bounds
RowBounds = new RectangleF(CurrentX, CurrentY, mColumnPointsWidth[mColumnPoint], RowsHeight[CurrentRow]);
// Filling the back of the CurrentRow
if (CurrentRow % 2 == 0)
g.FillRectangle(RowBackBrush, RowBounds);
else
g.FillRectangle(RowAlternatingBackBrush, RowBounds);
// Printing each visible cell of the CurrentRow
for (int CurrentCell = (int)mColumnPoints[mColumnPoint].GetValue(0); CurrentCell < (int)mColumnPoints[mColumnPoint].GetValue(1); CurrentCell++)
{
if (!TheDataGridView.Columns[CurrentCell].Visible) continue; // If the cell is belong to invisible column, then ignore this iteration
// Check the CurrentCell alignment and apply it to the CellFormat
if (TheDataGridView.Columns[CurrentCell].DefaultCellStyle.Alignment.ToString().Contains("Right"))
CellFormat.Alignment = StringAlignment.Far;
else if (TheDataGridView.Columns[CurrentCell].DefaultCellStyle.Alignment.ToString().Contains("Center"))
CellFormat.Alignment = StringAlignment.Center;
else
CellFormat.Alignment = StringAlignment.Near;
ColumnWidth = ColumnsWidth[CurrentCell];
RectangleF CellBounds = new RectangleF(CurrentX, CurrentY, ColumnWidth, RowsHeight[CurrentRow]);
// Printing the cell text
g.DrawString(TheDataGridView.Rows[CurrentRow].Cells[CurrentCell].EditedFormattedValue.ToString(), RowFont, RowForeBrush, CellBounds, CellFormat);
// Drawing the cell bounds
if (TheDataGridView.CellBorderStyle != DataGridViewCellBorderStyle.None) // Draw the cell border only if the CellBorderStyle is not None
g.DrawRectangle(TheLinePen, CurrentX, CurrentY, ColumnWidth, RowsHeight[CurrentRow]);
CurrentX += ColumnWidth;
}
CurrentY += RowsHeight[CurrentRow];
// Checking if the CurrentY is exceeds the page boundries
// If so then exit the function and returning true meaning another PagePrint action is required
if ((int)CurrentY > (PageHeight - TopMargin - BottomMargin))
{
CurrentRow++;
return true;
}
}
CurrentRow++;
}
CurrentRow = 0;
mColumnPoint++; // Continue to print the next group of columns
/////TitleEnd
if (IsWithTitleEnd)
{
StringFormat TitleFormat = new StringFormat();
TitleFormat.Trimming = StringTrimming.Word;
TitleFormat.FormatFlags = StringFormatFlags.NoWrap | StringFormatFlags.LineLimit | StringFormatFlags.NoClip;
if (IsCenterOnPage)
TitleFormat.Alignment = StringAlignment.Center;
else
TitleFormat.Alignment = StringAlignment.Near;
RectangleF TitleRectangle = new RectangleF((float)LeftMargin, CurrentY, (float)PageWidth - (float)RightMargin - (float)LeftMargin, g.MeasureString(TheTitleText, TheTitleFont).Height);
g.DrawString(TheTitleTextEnd, new System.Drawing.Font("Tahoma", 6, FontStyle.Bold, GraphicsUnit.Point), new SolidBrush(TheTitleColor), TitleRectangle, TitleFormat);
}
/////TitleEnd
if (mColumnPoint == mColumnPoints.Count) // Which means all columns are printed
{
mColumnPoint = 0;
return false;
}
else
return true;
}
// The method that calls all other functions
public bool DrawDataGridView(Graphics g)
{
try
{
Calculate(g);
DrawHeader(g);
bool bContinue = DrawRows(g);
return bContinue;
}
catch (Exception ex)
{
MessageBox.Show("Operation failed: " + ex.Message.ToString(), Application.ProductName + " - Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
return false;
}
}
} |