这是我的细胞绘画方法
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;
现在它可以正常工作,但是第一个和最后一个单元格的文本溢出。例如,如果dataGridView中的第一个单元格部分可见,则在行标题中呈现文本。同样,对于行中的最后一个单元格,文本从中流出。任何建议/解决方案表示赞赏。
答案 0 :(得分:2)
通过CellPainting
事件,您可以绘制到DataGridView
的整个可见区域,包括所有标题,仅包括滚动条。
它确实为您提供了Cell
矩形中e.CellBounds
的区域,但仍然可以让您在其外部绘制。
要将绘图限制为Cell
,最简单的方法是将e.Graphics.ClipBounds
更改为单元格的边界矩形。为确保行头不会溢出,我们将其限制为仅在行头的左侧开始,例如:
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);
现在,您绘制的所有内容都不会溢出。
注意:
TextRenderer
。还请注意:我无法再现下溢到标头中的效果。我可以想象,如果顶部的单元格不是很完全可见,则可能来自单元格的顶部,可能是负值。 (不过,我的DGV只允许我按整数行滚动。)要排除这些情况,您可能需要计算一个更好的剪切矩形,该矩形仅在标题单元格的下方开始。