从底部滚动到顶部时,DataGridView Paint Event 不绘制单元格边框
DataGridView Paint Event not drawing cell borders when scrolling from bottom to top
使用 C# WinForms,我在窗体上停靠(填充)了一个标准 DataGridView 控件。 DataGridView 列和行在加载表单时以编程方式创建一次。我在 Paint 事件中绘制了一些 header 和单元格边框。一切都很好。
我遇到的问题是滚动。当我向下滚动时,一切都很好。但是,当我向上滚动时,一些边框没有被绘制。当未绘制的区域显示在屏幕上时,我再次向下滚动,同时仍保留未绘制的区域在屏幕上,它重新绘制得很好。调试时我很难看到任何奇怪的东西,因为它完全是随机发生的;现在不能画一行,下一次可能是不同的边界。 "I know it paints fine" 因为当我向下滚动到底部时,一直向下滚动,一切都按应有的方式绘制。只有当我向上滚动时,随机行才不会被绘制,而且每次都可能是不同的行。
正如您将在下面的代码中看到的,我将不想绘制的边框设置为透明。即使我将未绘制的边框设置为 0 并将边框样式设置为 none,它也会产生相同的结果。
这是 GUI 错误还是刷新错误还是什么?
根据示例,我一直向下滚动,在向下滚动的过程中我看到所有边框都画得很好。我可以一遍又一遍地重做,结果相同,如下所示。
然后当我向上滚动时,一些边框没有随机绘制,正如您在带有文本的网格线上看到的那样20:00;行“20:00”应与行“21:00”相同,如下所示。
我用来绘画的代码是:
/// <summary>data grid view cell painting event : to draw custom cell borders</summary>
private void dgv_cell_painting(object sender, DataGridViewCellPaintingEventArgs e)
{
try
{
int row = e.RowIndex;
int column = e.ColumnIndex;
int last_col = data_grid_appointments.ColumnCount - 1;
int last_row = data_grid_appointments.RowCount - 1;
string row_tag = ((DataGridView)sender).Rows[row].Tag.ToString();
bool is_hour = (string.IsNullOrEmpty(row_tag) ? false : row_tag.EndsWith("00"));
switch (row < last_row)
{
case true: //not the last row
switch (row == 0
||
is_hour)
{
case true: //first row or row is on the hour
switch (column == -1)
{
case true:
e.PaintBackground(e.CellBounds, true);
e.PaintContent(e.CellBounds);
ControlPaint.DrawBorder
(
e.Graphics
, e.CellBounds
, Color.Transparent, 1, ButtonBorderStyle.Solid
, Color.Orange, 1, ButtonBorderStyle.Solid
, Color.Orange, 1, ButtonBorderStyle.Solid
, Color.Transparent, 1, ButtonBorderStyle.Solid
);
e.Graphics.DrawString
(
row_tag.Substring(0, 2) + ":" + row_tag.Substring(2)
, e.CellStyle.Font
, new SolidBrush(Color.Black)
, e.CellBounds
, new StringFormat()
{
Alignment = StringAlignment.Center
,
FormatFlags = StringFormatFlags.NoWrap
,
LineAlignment = StringAlignment.Center
}
);
e.Handled = true;
break;
default:
switch (column == data_grid_appointments.ColumnCount - 1)
{
case true:
e.PaintBackground(e.CellBounds, true);
e.PaintContent(e.CellBounds);
ControlPaint.DrawBorder
(
e.Graphics
, e.CellBounds
, Color.Transparent, 1, ButtonBorderStyle.Solid
, Color.Orange, 1, ButtonBorderStyle.Solid
, Color.Orange, 1, ButtonBorderStyle.Solid
, Color.Transparent, 1, ButtonBorderStyle.Solid
);
e.Handled = true;
break;
default:
e.PaintBackground(e.CellBounds, true);
e.PaintContent(e.CellBounds);
ControlPaint.DrawBorder
(
e.Graphics
, e.CellBounds
, Color.Transparent, 1, ButtonBorderStyle.Solid
, Color.Orange, 1, ButtonBorderStyle.Solid
, Color.Transparent, 1, ButtonBorderStyle.Solid
, Color.Transparent, 1, ButtonBorderStyle.Solid
);
e.Handled = true;
break;
}
break;
}
break;
default: //not the first column
if (column == -1
||
column == data_grid_appointments.ColumnCount - 1)
{
e.PaintBackground(e.CellBounds, true);
e.PaintContent(e.CellBounds);
ControlPaint.DrawBorder
(
e.Graphics
, e.CellBounds
, Color.Transparent, 1, ButtonBorderStyle.Solid
, Color.Transparent, 1, ButtonBorderStyle.Solid
, Color.Orange, 1, ButtonBorderStyle.Solid
, Color.Transparent, 1, ButtonBorderStyle.Solid
);
e.Handled = true;
}
break;
}
break;
default: //last row
switch (column == -1
||
column == last_col)
{
case true: //row header column OR very last column in the very last row
e.PaintBackground(e.CellBounds, true);
e.PaintContent(e.CellBounds);
ControlPaint.DrawBorder
(
e.Graphics
, e.CellBounds
, Color.Transparent, 1, ButtonBorderStyle.Solid
, Color.Transparent, 1, ButtonBorderStyle.Solid
, Color.Orange, 1, ButtonBorderStyle.Solid
, Color.Orange, 1, ButtonBorderStyle.Solid
);
e.Handled = true;
break;
default: //not the header column
e.PaintBackground(e.CellBounds, true);
e.PaintContent(e.CellBounds);
ControlPaint.DrawBorder
(
e.Graphics
, e.CellBounds
, Color.Transparent, 1, ButtonBorderStyle.Solid
, Color.Transparent, 1, ButtonBorderStyle.Solid
, Color.Transparent, 1, ButtonBorderStyle.Solid
, Color.Orange, 1, ButtonBorderStyle.Solid
);
e.Handled = true;
break;
}
break;
}
}
catch (Exception ex)
{}
}
因此,经过许多不同的方法和尝试后,我设法使用我最初在问题中发布的代码使边框始终如一地绘制。我注意到,当使用滚动条而不是鼠标滚动时,我得到了相同的结果。我添加了下面的代码,它起作用了,所有的线都被绘制出来并一致地显示出来。
private void data_grid_appointments_scroll(object sender, ScrollEventArgs e)
{
((DataGridView)sender).Invalidate();
}
使用 C# WinForms,我在窗体上停靠(填充)了一个标准 DataGridView 控件。 DataGridView 列和行在加载表单时以编程方式创建一次。我在 Paint 事件中绘制了一些 header 和单元格边框。一切都很好。
我遇到的问题是滚动。当我向下滚动时,一切都很好。但是,当我向上滚动时,一些边框没有被绘制。当未绘制的区域显示在屏幕上时,我再次向下滚动,同时仍保留未绘制的区域在屏幕上,它重新绘制得很好。调试时我很难看到任何奇怪的东西,因为它完全是随机发生的;现在不能画一行,下一次可能是不同的边界。 "I know it paints fine" 因为当我向下滚动到底部时,一直向下滚动,一切都按应有的方式绘制。只有当我向上滚动时,随机行才不会被绘制,而且每次都可能是不同的行。
正如您将在下面的代码中看到的,我将不想绘制的边框设置为透明。即使我将未绘制的边框设置为 0 并将边框样式设置为 none,它也会产生相同的结果。
这是 GUI 错误还是刷新错误还是什么?
根据示例,我一直向下滚动,在向下滚动的过程中我看到所有边框都画得很好。我可以一遍又一遍地重做,结果相同,如下所示。
然后当我向上滚动时,一些边框没有随机绘制,正如您在带有文本的网格线上看到的那样20:00;行“20:00”应与行“21:00”相同,如下所示。
我用来绘画的代码是:
/// <summary>data grid view cell painting event : to draw custom cell borders</summary>
private void dgv_cell_painting(object sender, DataGridViewCellPaintingEventArgs e)
{
try
{
int row = e.RowIndex;
int column = e.ColumnIndex;
int last_col = data_grid_appointments.ColumnCount - 1;
int last_row = data_grid_appointments.RowCount - 1;
string row_tag = ((DataGridView)sender).Rows[row].Tag.ToString();
bool is_hour = (string.IsNullOrEmpty(row_tag) ? false : row_tag.EndsWith("00"));
switch (row < last_row)
{
case true: //not the last row
switch (row == 0
||
is_hour)
{
case true: //first row or row is on the hour
switch (column == -1)
{
case true:
e.PaintBackground(e.CellBounds, true);
e.PaintContent(e.CellBounds);
ControlPaint.DrawBorder
(
e.Graphics
, e.CellBounds
, Color.Transparent, 1, ButtonBorderStyle.Solid
, Color.Orange, 1, ButtonBorderStyle.Solid
, Color.Orange, 1, ButtonBorderStyle.Solid
, Color.Transparent, 1, ButtonBorderStyle.Solid
);
e.Graphics.DrawString
(
row_tag.Substring(0, 2) + ":" + row_tag.Substring(2)
, e.CellStyle.Font
, new SolidBrush(Color.Black)
, e.CellBounds
, new StringFormat()
{
Alignment = StringAlignment.Center
,
FormatFlags = StringFormatFlags.NoWrap
,
LineAlignment = StringAlignment.Center
}
);
e.Handled = true;
break;
default:
switch (column == data_grid_appointments.ColumnCount - 1)
{
case true:
e.PaintBackground(e.CellBounds, true);
e.PaintContent(e.CellBounds);
ControlPaint.DrawBorder
(
e.Graphics
, e.CellBounds
, Color.Transparent, 1, ButtonBorderStyle.Solid
, Color.Orange, 1, ButtonBorderStyle.Solid
, Color.Orange, 1, ButtonBorderStyle.Solid
, Color.Transparent, 1, ButtonBorderStyle.Solid
);
e.Handled = true;
break;
default:
e.PaintBackground(e.CellBounds, true);
e.PaintContent(e.CellBounds);
ControlPaint.DrawBorder
(
e.Graphics
, e.CellBounds
, Color.Transparent, 1, ButtonBorderStyle.Solid
, Color.Orange, 1, ButtonBorderStyle.Solid
, Color.Transparent, 1, ButtonBorderStyle.Solid
, Color.Transparent, 1, ButtonBorderStyle.Solid
);
e.Handled = true;
break;
}
break;
}
break;
default: //not the first column
if (column == -1
||
column == data_grid_appointments.ColumnCount - 1)
{
e.PaintBackground(e.CellBounds, true);
e.PaintContent(e.CellBounds);
ControlPaint.DrawBorder
(
e.Graphics
, e.CellBounds
, Color.Transparent, 1, ButtonBorderStyle.Solid
, Color.Transparent, 1, ButtonBorderStyle.Solid
, Color.Orange, 1, ButtonBorderStyle.Solid
, Color.Transparent, 1, ButtonBorderStyle.Solid
);
e.Handled = true;
}
break;
}
break;
default: //last row
switch (column == -1
||
column == last_col)
{
case true: //row header column OR very last column in the very last row
e.PaintBackground(e.CellBounds, true);
e.PaintContent(e.CellBounds);
ControlPaint.DrawBorder
(
e.Graphics
, e.CellBounds
, Color.Transparent, 1, ButtonBorderStyle.Solid
, Color.Transparent, 1, ButtonBorderStyle.Solid
, Color.Orange, 1, ButtonBorderStyle.Solid
, Color.Orange, 1, ButtonBorderStyle.Solid
);
e.Handled = true;
break;
default: //not the header column
e.PaintBackground(e.CellBounds, true);
e.PaintContent(e.CellBounds);
ControlPaint.DrawBorder
(
e.Graphics
, e.CellBounds
, Color.Transparent, 1, ButtonBorderStyle.Solid
, Color.Transparent, 1, ButtonBorderStyle.Solid
, Color.Transparent, 1, ButtonBorderStyle.Solid
, Color.Orange, 1, ButtonBorderStyle.Solid
);
e.Handled = true;
break;
}
break;
}
}
catch (Exception ex)
{}
}
因此,经过许多不同的方法和尝试后,我设法使用我最初在问题中发布的代码使边框始终如一地绘制。我注意到,当使用滚动条而不是鼠标滚动时,我得到了相同的结果。我添加了下面的代码,它起作用了,所有的线都被绘制出来并一致地显示出来。
private void data_grid_appointments_scroll(object sender, ScrollEventArgs e)
{
((DataGridView)sender).Invalidate();
}