我有一个显示数据的datagridview,但是显示的数据没有填充datagridview的灰色背景显示的整个datagridview。我想要发生的是即使每行都没有数据,也要显示datagridview的网格线。
幸运的是,我找到了与此相关的代码,(此代码用于AutoSizeColumnsMode属性==填充,但是我需要将此属性设置为AllCells,以获取每列中更长的字符串) 起初我以为这是我正在寻找的代码:
private void dataGridView1_Paint(object sender, PaintEventArgs e)
{
int rowHeight = this.dataGridView1.RowTemplate.Height;
Pen slategraypen = new Pen(Brushes.SlateGray,0.5f);
slategraypen.LineJoin = System.Drawing.Drawing2D.LineJoin.Bevel;
slategraypen.Alignment = System.Drawing.Drawing2D.PenAlignment.Center;
int h = this.dataGridView1.ColumnHeadersHeight + (rowHeight) * (this.dataGridView1.NewRowIndex);
Bitmap rowImg = new Bitmap(this.dataGridView1.Width, rowHeight);
Graphics g = Graphics.FromImage(rowImg);
Rectangle rFrame = new Rectangle(1, 1, this.dataGridView1.Width-4, rowHeight);
g.DrawRectangle(slategraypen, rFrame);
Rectangle rFill = new Rectangle(2, 1, this.dataGridView1.Width - 4, rowHeight-1);
g.FillRectangle(Brushes.White, rFill);
// for rowheaders drawing. in my case, I dont want to show the rowheaders so I didnt include this in my code
//Rectangle rowHeader = new Rectangle(2, 2, this.dataGridView1.RowHeadersWidth - 2, rowHeight - 4);
//g.FillRectangle(new SolidBrush(this.dataGridView1.RowHeadersDefaultCellStyle.BackColor), rowHeader);
int w = this.dataGridView1.RowHeadersWidth-40;// -40 is the width of the row header that I dont want to show
for (int j = 0; j < this.dataGridView1.ColumnCount; j++)
{
w += this.dataGridView1.Columns[j].Width;
g.DrawLine(slategraypen, new Point(w, 0), new Point(w, rowHeight));
}
int loop = (this.dataGridView1.Height - h) / rowHeight;
for (int j = 0; j < loop + 1; j++)
{
e.Graphics.DrawImage(rowImg, 0, h + j * rowHeight);
}
}
这发生了:
但是,当我在列中输入长字符串时,会发生这种情况: 注意datagridview的右侧,由于为autosizecolumnsmode设置了fill属性,某些列会缩小
我试图将AutoSizeColumnsMode属性更改为allcell,这发生了: 每当我滚动水平滚动条时,下面绘制的线就会绘制在错误的位置。我不确定如果上下滚动垂直滚动条是否也会发生这种情况。
为此,我需要您的帮助来编写正确的代码。非常感谢您的帮助。
答案 0 :(得分:3)
这是一个快速的例子:
我使用CellPainting
来收集当前列的位置。这个小技巧让我忽略了任何滚动,列大小调整等。
方法如下:
List<int> colX = new List<int>();
private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (e.RowIndex == 0)
{
if (e.ColumnIndex == (dataGridView1.RowHeadersVisible ? -1 : 0)) colX.Clear();
colX.Add(e.CellBounds.X);
}
}
然后在Paint
事件中绘制“单元格”。
using System.Drawing.Drawing2D;
..
private void dataGridView1_Paint(object sender, PaintEventArgs e)
{
Rectangle cRect = dataGridView1.ClientRectangle;
int y0 = 0;
if (dataGridView1.ColumnHeadersVisible) y0 += dataGridView1.ColumnHeadersHeight;
int rhw = dataGridView1.RowHeadersVisible ? dataGridView1.RowHeadersWidth : 0;
foreach (DataGridViewRow row in dataGridView1.Rows)
{
y0 += row.Height;
}
int y1 = cRect.Height;
using (SolidBrush brush = new SolidBrush(dataGridView1.DefaultCellStyle.BackColor))
e.Graphics.FillRectangle(brush, cRect.Left + 2, y0, cRect.Right - 4, y1 - y0 - 2);
using (Pen gridPen1 = new Pen(dataGridView1.GridColor, 1f)
{ DashStyle = DashStyle.Dot })
using (Pen gridPen2 = new Pen(dataGridView1.GridColor, 1f)
{ DashStyle = DashStyle.Solid })
{
for (int i = 0; i < colX.Count; i++)
e.Graphics.DrawLine(gridPen1, colX[i] - 1, y0, colX[i] - 1, y1);
int y = y0;
while (y < cRect.Bottom)
{
e.Graphics.DrawLine(y == y0 ? gridPen2 : gridPen1,
cRect.Left, y, cRect.Right, y);
y += dataGridView1.Rows[0].Height;
}
if (rhw > 0) e.Graphics.DrawLine(gridPen1, rhw, y0, rhw, y1);
}
}
比您发现的代码简单得多,该代码还有其他一些错误,例如在Paint
事件中泄漏资源。.
注意:我通过用虚线绘制使伪单元格显得有些突出。
还要注意,该代码采用RowHeaders
。
如果您没有它们,也应该在Invalidate
事件中Scroll
:
private void dataGridView1_Scroll(object sender, ScrollEventArgs e)
{
dataGridView1.Invalidate();
}
也可以制作DGV DoubleBuffered以避免闪烁!
根据您的需求,您可能还需要Invalidate
参加一些其他活动,例如:
private void dataGridView1_ColumnWidthChanged(object sender, DataGridViewColumnEventArgs e)
{
dataGridView1.Invalidate();
}
其他可能包括ColumnAdded
,ColumnRemoved
。
更新:我已更正RowHeaders
的一个小错误。.