Reputation: 318
Here is my cell painting method.
DataGridView grid = (DataGridView)sender;
if ( e.RowIndex == -1 || e.ColumnIndex == -1 )
{ return; }
if ( ( grid.Rows [ e.RowIndex ].Cells [ e.ColumnIndex ].Value == null ) )
return;
Brush gridBrush = new SolidBrush(GridList[0].GridColor),backColorBrush = new SolidBrush(e.CellStyle.BackColor);
Pen gridLinePen = new Pen(gridBrush);
// Erase the cell.
e.Graphics.FillRectangle ( backColorBrush, e.CellBounds );
// Draw the grid lines (only the right and bottom lines;
// DataGridView takes care of the others).
e.Graphics.DrawLine ( gridLinePen, e.CellBounds.Left, e.CellBounds.Bottom - 1, e.CellBounds.Right - 1, e.CellBounds.Bottom - 1 );
e.Graphics.DrawLine ( gridLinePen, e.CellBounds.Right - 1, e.CellBounds.Top, e.CellBounds.Right - 1, e.CellBounds.Bottom );
// Draw the text content of the cell, ignoring alignment.
if ( e.Value != null )
{
Brush brush = new SolidBrush(Color.Red);
Brush brush1 = new SolidBrush(Color.Black);
String s = (String)e.Value;
System.Drawing.Rectangle rect = e.CellBounds;
List<int> pos = null;
if ( grid.Rows [ e.RowIndex ].Cells [ e.ColumnIndex ].Tag != null )
{
pos = ( List<int> ) grid.Rows [ e.RowIndex ].Cells [ e.ColumnIndex ].Tag;
}
String[] arr = s.Split('\n');
SizeF stringSize = TextRenderer.MeasureText(e.Graphics, arr[0], e.CellStyle.Font, e.CellBounds.Size);
float wid = stringSize.Height;
int X,Y;
for ( int i = 0; i < arr.Length; i++ )
{
if ( pos == null || pos.IndexOf ( i ) == -1 )
{
X = ( e.CellBounds.X );
Y = ( e.CellBounds.Y + i * ( ( int ) stringSize.Height ) );
TextRenderer.DrawText ( e.Graphics, arr [ i ], e.CellStyle.Font, new Point ( X, Y ), SystemColors.ControlText );
//e.Graphics.DrawString(arr[i], e.CellStyle.Font, brush1, new PointF(X, Y), StringFormat.GenericDefault);
}
else
{
X = ( e.CellBounds.X );
Y = ( e.CellBounds.Y + i * ( int ) stringSize.Height );
Brush brushForBox = new SolidBrush(Color.FromArgb(100, 120, 50,0));
e.Graphics.FillRectangle ( brushForBox, X, Y, e.CellBounds.Width, ( int ) stringSize.Height );
TextRenderer.DrawText ( e.Graphics, arr [ i ], e.CellStyle.Font, new Point ( X, Y ), SystemColors.ControlText );
//e.Graphics.DrawString(arr[i], e.CellStyle.Font, brush, new PointF(X, Y), StringFormat.GenericDefault);
}
}
}
//grid.InvalidateCell(-1, e.RowIndex);
e.Handled = true;
Now it works fine, but the text overflows for the first and last cells. For example, if the first cell in the dataGridView
is partially visible then the text is rendered in the row header. Similarly for the last cell in the row text flows out of it. Any suggestion/solution is appreciated.
Upvotes: 5
Views: 2076
Reputation: 5684
Setting the TextFormatFlags.PreserveGraphicsClipping
flag in your TextRenderer call should fix the issue for the RowHeaderCell overlap.
TextRenderer.DrawText(e.Graphics, arr[i], e.CellStyle.Font, new Point(X, Y), SystemColors.ControlText, TextFormatFlags.PreserveGraphicsClipping);
No need to play around with SetClip()
(which didn't work for me).
Upvotes: 0
Reputation: 54433
The CellPainting
event will let you draw onto the whole visible area of the DataGridView
, including all headers and excluding only scrollbars.
It does provide you with the Cell
's area in the e.CellBounds
rectangle but it will still let you draw outside of it.
To restrict your drawing to the Cell
the simplest way is to change the e.Graphics.ClipBounds
to the cell's bounding rectangle; to make sure no overflow into the rowheaders can occur we restrict it to only start left of the rowheader, maybe like this:
int rhw = grid.RowHeadersWidth;
Rectangle clip = e.CellBounds;
if (e.CellBounds.X < rhw)
clip = new Rectangle(rhw, clip.Y, clip.Width - rhw, clip.Height);
e.Graphics.SetClip(clip, CombineMode.Replace);
Now nothing you draw can overflow.
Notes:
TextRenderer
.Also note: I couldn't reproduce the effect of underflowing into the headers. I can imagine that it might come from the cell's top can lying in the negative if the top cell isn't quite fully visible. (My DGV only let's me scroll by integral rows, though.) To exclude these cases you may need to calculate a better clipping rectangle that only starts right below the header cells..
Upvotes: 3