Как максимально быстро загрузить большой массив строк в элемент управления списком MFC? - PullRequest
4 голосов
/ 23 октября 2008

У меня есть массив из 1000 строк для загрузки в поле со списком. Какой самый быстрый способ загрузить массив строк в поле со списком?

Есть ли другой способ, кроме как перебирать список строк, помещая каждую строку в поле со списком по одному?

А как скопировать данные поля со списком после загрузки в еще 10 других полей со списком?

Ответы [ 5 ]

5 голосов
/ 23 октября 2008

Если у вас есть 1000 строк, повторенных в 10 выпадающих списках, вы можете рассмотреть возможность использования выпадающего списка, нарисованного владельцем, который рисует строки на лету на основе индексов в вашем массиве, а не хранит их в выпадающем списке вообще. Намного быстрее, намного эффективнее памяти. Проверьте метод DrawItem и структуру DRAWITEMSTRUCT в интерактивной справке. По сути, вы должны сделать что-то вроде использования InitStorage и InsertString (как упомянуто NuSonic), чтобы создать 1000 пустых элементов в вашем комбинированном списке, и переопределить DrawItem для извлечения и нарисуйте требуемую строку, основываясь на индексе, так как она должна быть нарисована.

2 голосов
/ 23 октября 2008

Я не знаю ни одного способа атомарной загрузки нескольких строк, но есть несколько вещей, которые вы можете сделать, чтобы сделать процесс более эффективным:

  • Вызовите CComboBox :: InitStorage перед добавлением элементов для предварительного выделения памяти
  • Используйте InsertString вместо AddString, чтобы предотвратить запуск сортировки для каждого добавления (при условии, что стиль CBS_SORT включен)
0 голосов
/ 10 ноября 2017

У меня была эта проблема, и я решил ее двумя способами, в зависимости от # пунктов. Настройка не рисовать и инициализировать хранение не имеет никакого значения для меня. Заставить нарисовать владельца тоже можно, но у меня была тонна комбо-боксов. Предполагая фиксированный список для каждого выпадающего списка, который не меняет содержимого, список устанавливается один раз.

Очень большой # Предметы: Сделал поле со списком просто / отключено с помощью SetWindowText, чтобы установить начальную строку, и маленькая кнопка рядом с ним открыла диалоговое окно, позволяющее выбрать элемент из списка управления в режиме отчета для данных, которые были бы в комбо поле (может быть сделано в диалоге).

Умеренные # Предметы: Сделал пользовательский производный класс со списком, который переопределяет AddString, SelectString и обрабатывает OnDropDown. Когда вы добавляете элементы, они помещают их во временный вектор, а затем в SelectString (может также выполнить переопределение SetCurSel), он добавляет один элемент, который находит и выбирает. При выпадении вниз, он сбрасывает комбинированный список и добавляет все элементы и выбирает текущий выбранный. При падении выпадающего списка есть небольшое замедление, но при небольшом количестве предметов это не заметно.

Это заставило мои диалоги загружаться намного быстрее и все еще быть полностью функциональным без рисования владельцем.

0 голосов
/ 24 октября 2008

Возможно, быстрее, чем CComboBox с DrawItem, будет данные владельца CListCtrl . Это также послужит вашей цели дублирования поднабора элементов в другие списки, поскольку может использоваться общий источник данных.

Я предлагаю это, потому что CComboBox из 1000 пунктов не будет очень удобным для использования.

0 голосов
/ 23 октября 2008

Я рассмотрю возможность использования списка выбора вместо поля со списком для повышения производительности.

Общее практическое правило для повышения производительности при вставке множества элементов в список пользовательского интерфейса - вызывать перед вставкой и возвращать значение true после.

Вот правильный синтаксис

#define NB_ITEM 1000
#define ITEM_LENGTH 10

void CMFCComboDlg::InitMyCombo()
{
    CString _strData;
    m_cbMyCombo.SetRedraw( FALSE );

    m_cbMyCombo.Clear();

    m_cbMyCombo.InitStorage(NB_ITEM, ITEM_LENGTH); 

    for( int i = 0; i < NB_ITEM; i++ )
    {
        _strData.Format( L"Test %ld", i );
        m_cbMyCombo.InsertString( i, _strData );
    }

    m_cbMyCombo.SetCurSel(0);

    m_cbMyCombo.SetRedraw( TRUE );
}

РЕДАКТИРОВАТЬ: улучшить решение, чтобы включить предложение smacl

...