You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

DataGridView列右移功能优化求助:大文件卡顿问题

DataGridView列右移功能优化方案

问题背景

我给DataGridView做了个上下文菜单,用来处理各种非规范的制表符分隔旧财务数据。现在要实现指定列右侧所有列右移的功能,试了.Insert、.Add和.Clone方法都没成功。当前代码处理大文件时卡顿严重,求优化思路。另外最终会改成传递列表,不用全局列表。

原实现代码

private void dgv_MoveColumnRight(DataGridView dgv, int cIndex)
{
    dgv.ColumnCount = dgv.ColumnCount + 1;
    int cCount = dgv.ColumnCount - 2;
    if (dgv.RowCount <= 1) { return; }
    while (cCount >= cIndex)
    {
        dgv_CopyColumn(dgv, cCount);
        dgv_PasteColumn(dgv, cCount + 1);
        cCount--;
        Application.DoEvents();
    }
    for (int n = 0; n < dgv.RowCount; n++)
    {
        dgv.Rows[n].Cells[cIndex].Value = " ";
    }
}

List<string> colData = new List<string>();
private void dgv_CopyColumn(DataGridView dgv, int cIndex)   
{
    colData.Clear();
    for (int n = 0; n < dgvStatement.RowCount; n++)
    {
        if(dgv.Rows[n].Cells[cIndex].Value != null)
        {
            colData.Add(dgv.Rows[n].Cells[cIndex].Value.ToString());
        }
        else
        {
            colData.Add(" ");
        }
        showMe.Comment = n.ToString() + "	" + colData[n];
    }
}

private void dgv_PasteColumn(DataGridView dgv, int cIndex)  
{
    if (colData.Count == 0) { return; }
    for (int n = 0; n < dgvStatement.RowCount; n++)
    {
        dgv.Rows[n].Cells[cIndex].Value = colData[n];
    }
}

优化思路

  • 暂停控件重绘:操作前后分别调用dgv.SuspendLayout()和dgv.ResumeLayout(false),避免每一步单元格修改都触发UI刷新,大幅降低卡顿。
  • 直接操作数据源:如果DataGridView绑定了DataTable这类数据源,直接在数据源层面插入列、转移数据,控件会自动同步,比直接操作单元格效率高一个数量级。
  • 移除冗余UI操作:删掉Application.DoEvents()(会强制刷新UI,加重负担)和showMe.Comment的实时更新(调试用代码,正式场景无意义)。
  • 替换全局列表为局部传递:让dgv_CopyColumn返回List<string>,直接作为参数传给dgv_PasteColumn,避免全局状态的潜在问题。
  • 批量设置空值:不用逐行设置目标列的空值,可通过遍历数据源行或者利用列默认值一次性处理。

优化后示例代码(基于数据源操作)

假设你的DataGridView绑定的是DataTable,可以这样实现:

private void MoveColumnsRight(DataGridView dgv, int targetColumnIndex)
{
    if (dgv.DataSource is not DataTable dt || dt.Rows.Count == 0) return;
    
    // 暂停控件重绘
    dgv.SuspendLayout();
    
    // 在目标位置右侧插入新列
    dt.Columns.Add($"TempCol_{Guid.NewGuid()}", typeof(string));
    // 从右往左移动列数据
    for (int colIdx = dt.Columns.Count - 2; colIdx >= targetColumnIndex; colIdx--)
    {
        foreach (DataRow row in dt.Rows)
        {
            row[colIdx + 1] = row[colIdx] ?? " ";
        }
    }
    // 清空目标列
    foreach (DataRow row in dt.Rows)
    {
        row[targetColumnIndex] = " ";
    }
    
    // 恢复控件重绘
    dgv.ResumeLayout(false);
    dgv.Refresh();
}

优化后示例代码(直接操作控件,无数据源绑定)

private void dgv_MoveColumnRight(DataGridView dgv, int cIndex)
{
    if (dgv.RowCount <= 1) return;
    
    // 暂停控件重绘
    dgv.SuspendLayout();
    
    dgv.ColumnCount += 1;
    int cCount = dgv.ColumnCount - 2;
    
    while (cCount >= cIndex)
    {
        // 直接复制列数据,用局部变量替代全局列表
        var columnData = new List<string>();
        foreach (DataGridViewRow row in dgv.Rows)
        {
            columnData.Add(row.Cells[cCount].Value?.ToString() ?? " ");
        }
        // 粘贴到右侧列
        for (int i = 0; i < dgv.Rows.Count; i++)
        {
            dgv.Rows[i].Cells[cCount + 1].Value = columnData[i];
        }
        cCount--;
    }
    
    // 批量清空目标列
    foreach (DataGridViewRow row in dgv.Rows)
    {
        row.Cells[cIndex].Value = " ";
    }
    
    // 恢复重绘
    dgv.ResumeLayout(false);
    dgv.Refresh();
}

内容的提问来源于stack exchange,提问作者Mike Sr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 10:46:00