相邻单元格(顶部和左侧)在选中时绘制在自定义绘制的边框上
Adjacent cells (Top and Left) drawing over custom painted border when selected
出现上述问题的图片:
这是我用来在 select 个单元格周围绘制边框的代码:
private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (e.ColumnIndex > 0 && e.RowIndex > -1)
{
if (e.Value != null && (!e.Value.Equals("0")) && (!e.Value.Equals("-")))
{
double d = Convert.ToDouble(e.Value);
if (e.ColumnIndex == 2)
{
int limit = Convert.ToInt16(numericUpDown1.Value);
if (d > limit)
{
int pWidth = 1;
Pen p = new Pen(Color.Red, pWidth);
e.PaintBackground(e.CellBounds, true);
e.PaintContent(e.CellBounds);
int x = e.CellBounds.Left – pWidth;
int y = e.CellBounds.Top – pWidth;
int w = e.CellBounds.Width;
int h = e.CellBounds.Height;
e.Graphics.DrawRectangle(p, x,y,w,h);
e.Handled = true;
}
}
}
}
}
有什么办法让它们不消失?它不会发生在底部和右边界。我尝试了几件事,包括:
- 禁用边框并为所有单元格绘制我自己的边框(同一问题)
- 将绘制矩形调整到单元格内部(不喜欢这种外观)
- 处理 CellEnter/CellLeave/CellClick 使行和列无效以尝试让自定义边框单元格在顶部重新绘制
问题是两个绘制事件发生冲突:
- 您的 CellPaint 绘制了漂亮的红色边框..
- ..和之后,系统绘制选定的单元格,破坏相邻单元格中的红色边框。
实际上更糟,这取决于你如何移动选区,尤其是当你向上或向下移动它时,因为现在不仅选区被绘制而且之前的选区被恢复,破坏了单元格中的红色边框高于或低于!
我不确定为什么会不对称地发生这种情况;也许这是旧的 DrawRectanlge 错误,它倾向于将尺寸缩小一个。 (这就是为什么你不能绘制大小为 1 的矩形;你需要填充它!)或者事件的顺序可能有些奇怪..
尽管如此,您只需使用 InvalidateCell
:
强制重新绘制受影响的单元格即可解决问题
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
DataGridViewCell cell = dataGridView1.CurrentCell;
if (cell.ColumnIndex < dataGridView1.ColumnCount - 1)
{
dataGridView1.InvalidateCell(cell.ColumnIndex + 1, cell.RowIndex);
if (cell.RowIndex > 0)
dataGridView1.InvalidateCell(cell.ColumnIndex + 1, cell.RowIndex - 1);
if (cell.RowIndex < DGV.ColumnCount -1)
dataGridView1.InvalidateCell(cell.ColumnIndex + 1, cell.RowIndex + 1);
}
}
您可能希望针对您自己绘制的列对其进行优化..
我尝试了 TaWs 的回答(当时能够发表评论),它并没有解决问题,但让我开始思考。我需要在绘制任何其他单元格时随时使这些单元格无效,因此我将事件处理程序添加到以下内容:
- CellMouseDown
- CellMouseUp
- 选择已更改
- Form_Activated
我没有使相邻单元格无效,因为它似乎不起作用,而是使该列的显示列矩形无效,因为它是当前唯一具有自定义边框单元格的单元格。
出现上述问题的图片:
这是我用来在 select 个单元格周围绘制边框的代码:
private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (e.ColumnIndex > 0 && e.RowIndex > -1)
{
if (e.Value != null && (!e.Value.Equals("0")) && (!e.Value.Equals("-")))
{
double d = Convert.ToDouble(e.Value);
if (e.ColumnIndex == 2)
{
int limit = Convert.ToInt16(numericUpDown1.Value);
if (d > limit)
{
int pWidth = 1;
Pen p = new Pen(Color.Red, pWidth);
e.PaintBackground(e.CellBounds, true);
e.PaintContent(e.CellBounds);
int x = e.CellBounds.Left – pWidth;
int y = e.CellBounds.Top – pWidth;
int w = e.CellBounds.Width;
int h = e.CellBounds.Height;
e.Graphics.DrawRectangle(p, x,y,w,h);
e.Handled = true;
}
}
}
}
}
有什么办法让它们不消失?它不会发生在底部和右边界。我尝试了几件事,包括:
- 禁用边框并为所有单元格绘制我自己的边框(同一问题)
- 将绘制矩形调整到单元格内部(不喜欢这种外观)
- 处理 CellEnter/CellLeave/CellClick 使行和列无效以尝试让自定义边框单元格在顶部重新绘制
问题是两个绘制事件发生冲突:
- 您的 CellPaint 绘制了漂亮的红色边框..
- ..和之后,系统绘制选定的单元格,破坏相邻单元格中的红色边框。
实际上更糟,这取决于你如何移动选区,尤其是当你向上或向下移动它时,因为现在不仅选区被绘制而且之前的选区被恢复,破坏了单元格中的红色边框高于或低于!
我不确定为什么会不对称地发生这种情况;也许这是旧的 DrawRectanlge 错误,它倾向于将尺寸缩小一个。 (这就是为什么你不能绘制大小为 1 的矩形;你需要填充它!)或者事件的顺序可能有些奇怪..
尽管如此,您只需使用 InvalidateCell
:
private void dataGridView1_SelectionChanged(object sender, EventArgs e)
{
DataGridViewCell cell = dataGridView1.CurrentCell;
if (cell.ColumnIndex < dataGridView1.ColumnCount - 1)
{
dataGridView1.InvalidateCell(cell.ColumnIndex + 1, cell.RowIndex);
if (cell.RowIndex > 0)
dataGridView1.InvalidateCell(cell.ColumnIndex + 1, cell.RowIndex - 1);
if (cell.RowIndex < DGV.ColumnCount -1)
dataGridView1.InvalidateCell(cell.ColumnIndex + 1, cell.RowIndex + 1);
}
}
您可能希望针对您自己绘制的列对其进行优化..
我尝试了 TaWs 的回答(当时能够发表评论),它并没有解决问题,但让我开始思考。我需要在绘制任何其他单元格时随时使这些单元格无效,因此我将事件处理程序添加到以下内容:
- CellMouseDown
- CellMouseUp
- 选择已更改
- Form_Activated
我没有使相邻单元格无效,因为它似乎不起作用,而是使该列的显示列矩形无效,因为它是当前唯一具有自定义边框单元格的单元格。