有没有办法让row.DefaultCellStyle.BackColor修复,尽管重新绘制?

时间:2015-12-18 10:55:08

标签: c# .net windows winforms datagridview

现在我正在使用以下内容为我的datagridview行着色:

foreach (DataGridViewRow row in dataGridView1.Rows)
{
    if ((row.Index % 2) == 0)
    {
        row.DefaultCellStyle.BackColor = Color.NavajoWhite;
    }
}

这对于第一次加载数据时很好。但是,我也使用第三方库来过滤像Excel那样的列(http://www.codeproject.com/Articles/33786/DataGridView-Filter-Popup)。它工作得很好,但问题是这个代码重新绘制每次应用的过滤(到纯白色)的datagridview。如果我愿意,我可以捕获必要的事件以在每次过滤后重新绘制我的行,例如

dataGridView1_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
然而,如果我有大型矩阵(数十万行),效率非常低。

问题在于是否有办法使行背景颜色固定,尽管过滤完成了重新绘制。在我看来,这可能是一个长镜头,所以任何建议,以解决这个问题或使其更快,更有效,将不胜感激。

2 个答案:

答案 0 :(得分:2)

尝试仅为每个单元格处理CellPainting事件

private void dataGridView1_CellPainting(object sender,
System.Windows.Forms.DataGridViewCellPaintingEventArgs e)
{
     if ((e.RowIndex % 2) == 0)         
         e.CellStyle.BackColor = Color.NavajoWhite;         
}

答案 1 :(得分:1)

自己尝试the MSDN example之后我发现它并不那么容易,自从我使用DataGridView以来已经很长时间了,所以这里就是这样。

以下示例提供备用行背景,而不管单元格的样式噱头。只需在表单上放置一个网格,并在Form的构造函数中调用此方法:

private void InitializeGrid()
{
    dgv.Columns.Add("colId", "Id");
    dgv.Columns.Add("colName", "Name");

    for (int c = 1; c <= 100; c++)
    {
        int r = dgv.Rows.Add();
        dgv.Rows[r].SetValues(c, "Person" + c);
    }

    dgv.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
}

它将创建一个您可以修补的示例网格。

现在有趣的是:

private void dgv_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
{
    // Don't paint focused/selected rows
    if ((e.State & DataGridViewElementStates.Selected) ==
                DataGridViewElementStates.Selected)
        return;

    // This informs the event that we don't want it to paint the background, we'll take 
    // care of it instead.
    e.PaintParts &= ~DataGridViewPaintParts.Background;

    // Calculate row rectangle (based off the MSDN example)
    var rowBounds = new Rectangle(
        dgv.RowHeadersWidth, e.RowBounds.Top,
        dgv.Columns.GetColumnsWidth(DataGridViewElementStates.Visible) - dgv.HorizontalScrollingOffset + 1,
        e.RowBounds.Height);

    // Paint row headers, for some reason they are part of the Background.
    e.PaintHeader(true);

    // Now custom-paint the row background
    using (Brush backBrush = new SolidBrush(Color.NavajoWhite))
    {
        if (e.RowIndex % 2 != 0)
            // If RowIndex is not divisible by 2 then paint custom color
            e.Graphics.FillRectangle(backBrush, rowBounds);
        else
            // Otherwise just let the grid paint the row
            e.PaintCells(rowBounds, DataGridViewPaintParts.Background);
    }
}

确保您还拥有using System.Drawing;指令。请注意,此示例仅适用于dgv.SelectionMode = DataGridViewSelectionMode.FullRowSelect;。对于常规的单元格选择模式,它有点棘手,你也必须处理这种情况。

渲染非常快,应该可以帮助您完成任务。如果没有,那么至少你有更多的选择可以考虑。在适当的时候改变单元格的样式也应该可以正常工作,但可能会导致闪烁或影响响应。