在 DataGridViewComboBox 列上设置值非常慢

Posted

技术标签:

【中文标题】在 DataGridViewComboBox 列上设置值非常慢【英文标题】:Setting Value on DataGridViewComboBox column very slow 【发布时间】:2015-01-21 14:25:19 【问题描述】:

我有一个 DataGridView,我向其中添加了一个 DataGridViewComboBoxColumn,添加值,并通过遍历网格行来设置值。选定的值是来自另一个行单元格的值。这非常慢,我不确定我是否使用了最佳实践。对于具有 3000 行的网格,这需要两分钟才能完成。我尝试通过行数进行迭代并使用 foreach 循环(在下面的注释代码中)具有相同的结果。有没有更快的方法来做到这一点?这是我的代码:

DataGridViewComboBoxColumn cmb = new DataGridViewComboBoxColumn();
        cmb.HeaderText = "New Class";
        cmb.Name = "cmb";

        foreach (DataGridViewRow row in dgClasses.Rows)
        
            if (row.Cells[0].Value != null)
            
                cmb.Items.Add(row.Cells[0].Value);
            
        

        dgProducts.Columns.Add(cmb);

        for (int i = 0; i < dgProducts.Rows.Count; i++)
        
            dgProducts.Rows[i].Cells["cmb"].Value = dgProducts.Rows[i].Cells["Class"].Value;
        

        //foreach (DataGridViewRow row in dgProducts.Rows)
        //
        //   row.Cells["cmb"].Value = row.Cells["Class"].Value;
        //

【问题讨论】:

你有更多关于它为什么这么慢的细节吗?我无法使用两个 DGViews 的数据源的简单类来复制您的问题 - 甚至在第 0 列中用 3000 个唯一字符串值填充 dgClasses 并用 3000 个对象填充 dgProducts,每个对象都引用一个唯一类。将秒表放入我在您发布的代码上测试了单线程和后台工作人员,他们分别在每次试验的 0.4~ 和 0.5~ 秒内完成了工作。 上面的代码就是我将组合框列添加到 dgProducts 网格的方法中的全部内容。如果我在 dgProducts.Columns.Add(cmb); 之后评论代码该程序如预期的那样非常快。绝对是值的设置很慢。 dgClasses 网格只有几行,所以每个组合框不会有很多值。不到20个左右。在以前的方法中,我通过 ReadXml 加载 dgProducts 网格,然后加载到 DataView 以过滤行。我认为这不会影响以后的网格迭代吗? 我不这么认为,但这是您的代码和我的实现之间唯一真正的区别。例如:dgClasses 的 DataSource 是一个 List&lt;Products&gt;,只有一个属性包含字符串 "Class1", "Class2", ..., "Class20" ,而 dgProducts 的 DataSource 是一个 List&lt;Classes&gt;,它包含相同的属性和第二个字符串类型 "Foo1", ..., "Foo3000" 。将 dgClasses 减少到 20 个项目现在平均单线程和后台线程运行时间为 0.02~ 和 0.04~ 秒。也许它与您的 DataSource 和属性数量有关?令人费解。 更多研究我发现将 DataPropertyName 设置为另一列会绑定 ComboBox。不需要行迭代并且加载速度非常快。 :) 感谢您的努力! 干得好!我很高兴你能弄清楚。 【参考方案1】:

我添加了 DataPropertyName 并摆脱了网格行的循环。现在加载速度非常快。

private void AddClassCombobox()
    
        DataGridViewComboBoxColumn cmb = new DataGridViewComboBoxColumn();
        cmb.HeaderText = "New Class";
        cmb.Name = "cmb";
        cmb.DataPropertyName = "Class";  // << Added this

        foreach (DataGridViewRow row in dgClasses.Rows)
        
            if (row.Cells[0].Value != null)
            
                cmb.Items.Add(row.Cells[0].Value);
            
        

        dgProducts.Columns.Add(cmb);
    

【讨论】:

以上是关于在 DataGridViewComboBox 列上设置值非常慢的主要内容,如果未能解决你的问题,请参考以下文章

DataGridViewCombobox 列中的自动完成有啥奇怪的行为?

值未显示在 DataGridViewComboBox 控件上

如何在 DataGridViewComboBox 列中绘制非活动行?

将 DataGridViewComboBox 默认设置为等于现有 DataGridView 列

DataGridViewComboBox 数据源

dataGridViewCombobox 值未保存在导航器上保存按钮单击