【问题标题】:Adjacent cells (Top and Left) drawing over custom painted border when selected选中时,相邻单元格(顶部和左侧)在自定义绘制边框上绘制
【发布时间】:2015-02-12 01:02:44
【问题描述】:

显示上述问题的图片:

http://imgur.com/a/vFvRr

这是我用来在选定单元格周围绘制边框的代码:

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 处理为 .Invalidate 行和列以尝试让自定义边框单元格在顶部重新绘制

【问题讨论】:

    标签: c# winforms datagridview


    【解决方案1】:

    问题是两个绘制事件是冲突的:

    • 您的 CellPaint 绘制了漂亮的红色边框..
    • ..之后,系统会绘制选定的单元格,破坏相邻单元格中的红色边框。

    实际上更糟糕,这取决于你如何移动选区,尤其是当你向上或向下移动它时,因为现在不仅选区被绘制,而且之前的选区也恢复了,破坏了上面单元格中的红色边框或下面也是!

    我不确定为什么会不对称地发生这种情况;也许是旧的 DrawRectanlge 错误,它倾向于将尺寸缩小一倍。 (这就是为什么你不能绘制一个大小为 1 的 Rectangle;你需要填充它!)或者事件的顺序可能有些奇怪..

    尽管如此,您只需使用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);
        }
    } 
    

    您可能希望针对您的所有者绘制的列对其进行优化..

    【讨论】:

      【解决方案2】:

      我尝试了 TaWs 的答案(当时能够发表评论),它没有解决问题,但让我思考。我需要在绘制任何其他单元格时使这些单元格无效,因此我将事件处理程序添加到以下内容:

      • CellMouseDown
      • CellMouseUp
      • 选择已更改
      • Form_Activated

      我没有使相邻的单元格无效,因为它似乎没有工作,而是使该列的显示列矩形无效,因为它是当前唯一具有自定义边框单元格的列。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-05-02
        • 1970-01-01
        • 2019-08-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-10-25
        • 1970-01-01
        相关资源
        最近更新 更多