Установка значения в столбце DataGridViewComboBox очень медленная

У меня есть 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;
        //}

person Blaze    schedule 21.01.2015    source источник
comment
У вас есть более подробная информация о том, почему это может быть так медленно? Мне не удалось воспроизвести вашу проблему, используя простые классы для источников данных для двух DGViews - даже заполнив dgClasses 3000 уникальными строковыми значениями в столбце 0 и заполнив dgProducts 3000 объектами, каждый из которых относится к одному из уникальных классов. Включив секундомер, я протестировал однопоточный и фоновый рабочий код на вашем опубликованном коде, и соответственно они завершали работу за 0,4 ~ и 0,5 ~ секунды каждый раз.   -  person OhBeWise    schedule 21.01.2015
comment
Приведенный выше код — это все, что есть в моем методе добавления столбца со списком в сетку dgProducts. Если я прокомментирую код после dgProducts.Columns.Add(cmb); программа работает очень быстро, как и ожидалось. Это определенно медленная установка значения. В сетке dgClasses будет всего несколько строк, поэтому в каждом поле со списком не будет много значений. Меньше 20 или около того. В предыдущем методе я загружаю сетку dgProducts через ReadXml, а затем загружаю в DataView для фильтрации строк. Я не думаю, что это повлияет на более позднюю итерацию сетки, не так ли?   -  person Blaze    schedule 22.01.2015
comment
Я бы так не думал, но это единственная реальная разница между вашим кодом и моей реализацией. Например: DataSource dgClasses — это List<Products> только с одним свойством, которое содержит строки { "Class1", "Class2", ..., "Class20" }, а DataSource dgProducts — это List<Classes>, который содержит то же свойство и второй строковый тип { "Foo1", ..., "Foo3000" }. Перемещение dgClasses до 20 элементов приводит к тому, что однопотоковое и фоновое выполнение теперь занимает в среднем 0,02~ и 0,04~ секунды. Может быть, это как-то связано с вашим источником данных и количеством свойств? Загадочный.   -  person OhBeWise    schedule 22.01.2015
comment
Дополнительные исследования Я обнаружил, что установка DataPropertyName в другой столбец связывает ComboBox. Нет необходимости в итерации строки и загружается очень быстро. :) Спасибо за ваши старания!   -  person Blaze    schedule 23.01.2015
comment
Отличная работа! Я рад, что ты смог разобраться.   -  person OhBeWise    schedule 23.01.2015


Ответы (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);
    }
person Blaze    schedule 23.01.2015