将 DataGridView 的行高设置为自定义值很慢

Setting the height of Rows of a DataGridView to a custom value is slow

我正在处理一个 WinForms 项目,我有一个包含 5 个数据绑定 DataGridView 控件的表单。
我需要为每一行设置自定义高度:

我使用以下代码:

private void dgv_RowPrePaint(object sender, DataGridViewRowPrePaintEventArgs e)
{
     dgv.SuspendLayout();
     var rowHeight = CalculateRowHeight((MyDto)dgvBatches.Rows[e.RowIndex].DataBoundItem));
     dgvBatches.Rows[e.RowIndex].Height = rowHeight;
     dgvBatches.ResumeLayout();
}

它可以工作,但 DataGridView 加载和滚动很慢。
有什么技巧可以提高加载和滚动速度吗?

不断引发RowPrePaint事件:每次滚动DataGridView(多次),单击一个Cell(2次或更多次:1次用于Header),当您将鼠标指针悬停在1 个或多个单元格,当您更改值等时
看来Rows的高度只有在给Control分配了一个数据源的时候才需要计算,我的建议是数据绑定完成后才进行这个操作。

控件通知绑定完成,引发 DataBindingComplete 事件。
在其处理程序中,您可以暂停布局,执行所需的计算并将结果分配给添加到网格的每一行:

private void dgv_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
    if (e.ListChangedType == ListChangedType.Reset) {
        dgvBatches.SuspendLayout();
        for (int i = 0; i < dgvBatches.Rows.Count - 1; i++) {
            if (i == dgvBatches.NewRowIndex) continue;
            var rowHeight = CalculateRowHeight((MyDto)dgvBatches.Rows[e.RowIndex].DataBoundItem));
            dgvBatches.Rows[e.RowIndex].Height = rowHeight;
        }
        dgvBatches.ResumeLayout(false);
    }
    else if (e.ListChangedType == ListChangedType.ItemChanged) {
        // Partner with CellValueChanged
    }
}

DataBindingComplete 事件让您知道导致绑定通知的原因。
当您第一次为 DataSource 属性 赋值时,e.ListChangedType 成员将设置为 ListChangedType.Reset,当 DataBoundItem 值更改时,它将是 ListChangedType.ItemChanged,这样您就可以确定在这种情况下需要采取什么行动。
如果单个 Cell 值发生变化,您可能不需要重新计算所有内容,如果它完全可以更改的话。
如果确实如此,您可以调整单个行的大小,或调整当前行之后的所有行的大小,等等。

由于此布局可能会变得复杂,您还可以从双缓冲 DataGridView 中获益,除非您有 高数字 1行数(看起来不像,但可能是)。

尝试将其添加到表单构造器中,看看是否更好:

var flags = BindingFlags.Instance | BindingFlags.NonPublic;
dgvBatches.GetType().GetProperty("DoubleBuffered", flags).SetValue(dgvBatches, true);

1 - 高数 取决于多种因素,而不仅仅是行数。当您测试网格如何响应不同形式的交互时,您知道行数是,但您发现它没有按预期做出反应。