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

如何在DataGridView中将选中行移至顶部并优化性能?

高效实现DataGridView选中行移至DataTable顶部

我明白你遇到的痛点——原代码通过两次遍历DataGridView的UI行来重组数据,不仅在数据量大时性能拉胯,还存在冗余逻辑。下面给出两种针对性的高效优化方案,重点减少遍历开销、避开UI层低效操作,直接针对DataTable核心数据处理:

方案一:基于HashSet快速筛选,单次遍历原DataTable

这个方案的核心是先把选中行存入HashSet(实现O(1)时间复杂度的存在性判断),然后仅遍历一次原DataTable,就能完成新表的重组:

if (MainWindow.table_G_Level_Data.dataGridView1.SelectedRows.Count <= 0)
    return;

// 1. 获取绑定的原DataTable,直接操作数据源而非UI控件
var originalTable = (DataTable)MainWindow.table_G_Level_Data.dataGridView1.DataSource;

// 2. 收集选中行,用HashSet加速后续判断
var selectedRowSet = new HashSet<DataRow>();
var selectedRowList = new List<DataRow>();
foreach (DataGridViewRow uiRow in MainWindow.table_G_Level_Data.dataGridView1.SelectedRows)
{
    var dataRow = ((DataRowView)uiRow.DataBoundItem).Row;
    selectedRowSet.Add(dataRow);
    selectedRowList.Add(dataRow);
}

// 3. 创建新表并导入数据
var newTable = originalTable.Clone();
// 先导入选中行实现置顶
foreach (var row in selectedRowList)
{
    newTable.ImportRow(row);
}
// 再导入未选中行,仅遍历一次原DataTable
foreach (DataRow row in originalTable.Rows)
{
    if (!selectedRowSet.Contains(row))
    {
        newTable.ImportRow(row);
    }
}

// 4. 重新绑定并恢复选中状态
MainWindow.table_G_Level_Data.dataGridView1.DataSource = newTable;
for (int i = 0; i < selectedRowList.Count; i++)
{
    MainWindow.table_G_Level_Data.dataGridView1.Rows[i].Selected = true;
}

优化点说明:

  • 避免重复遍历UI行:UI元素的访问开销远高于直接操作DataTable,这里仅遍历一次选中行集合,再遍历一次原DataTable(比遍历UI行效率提升明显)
  • HashSet加速判断:Contains操作的时间复杂度为O(1),替代原代码的两次循环判断,大幅减少计算量
  • 逻辑更清晰:明确分离“收集选中行”和“重组新表”的步骤,减少冗余代码

方案二:利用DataView排序(无需创建新表)

如果你的需求只是显示上置顶选中行,不需要修改原DataTable的物理顺序,这个轻量方案更适合:给DataTable加一个临时排序列,通过标记优先级实现显示置顶:

if (MainWindow.table_G_Level_Data.dataGridView1.SelectedRows.Count <= 0)
    return;

var originalTable = (DataTable)MainWindow.table_G_Level_Data.dataGridView1.DataSource;

// 1. 添加临时排序列(不存在则创建)
if (!originalTable.Columns.Contains("SortPriority"))
{
    originalTable.Columns.Add("SortPriority", typeof(int));
}

// 2. 设置排序优先级:选中行设为0(优先显示),未选中设为1
foreach (DataRow row in originalTable.Rows)
{
    row["SortPriority"] = 1;
}
foreach (DataGridViewRow uiRow in MainWindow.table_G_Level_Data.dataGridView1.SelectedRows)
{
    ((DataRowView)uiRow.DataBoundItem).Row["SortPriority"] = 0;
}

// 3. 通过DataView排序实现置顶
var sortedView = new DataView(originalTable);
sortedView.Sort = "SortPriority ASC";
MainWindow.table_G_Level_Data.dataGridView1.DataSource = sortedView;

// 可选:如果不需要保留临时列,排序后可移除
// originalTable.Columns.Remove("SortPriority");

方案优势:

  • 无需创建新DataTable,内存开销更小
  • 操作更轻量,适合数据量较大的场景
  • 原DataTable物理顺序不变,仅通过视图排序改变显示效果

根据你的实际需求选择方案:如果需要永久修改DataTable的行顺序,用方案一;如果只是临时显示置顶,方案二更高效。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 06:33:52