Comment charger un grand nombre de chaînes dans un contrôle MFC combobox aussi rapidement que possible?

StackOverflow https://stackoverflow.com/questions/229395

Question

J'ai un tableau de 1000 chaînes à charger dans une liste déroulante. Quel est le moyen le plus rapide de charger le tableau de chaînes dans la liste déroulante?

Existe-t-il un moyen autre que de parcourir la liste des chaînes, de placer chaque chaîne dans la liste déroulante une par une?

Et comment copier les données de la liste déroulante une fois chargées dans quelque 10 autres boîtes combo?

Était-ce utile?

La solution

Si vous avez 1 000 chaînes répétées dans 10 comboboxes, vous pouvez envisager d'utiliser une liste déroulante dessinée par le propriétaire, qui dessine les chaînes à la volée en fonction d'indices dans votre tableau, plutôt que de les stocker dans la liste déroulante. Bien plus rapide, bien plus efficace en mémoire. Consultez la méthode DrawItem et la structure DRAWITEMSTRUCT dans l'aide en ligne. En gros, vous feriez quelque chose comme utiliser InitStorage et InsertString (comme mentionné par NuSonic) pour créer vos 1 000 éléments vides dans votre liste déroulante et remplacer DrawItem pour extraire et dessiner la chaîne requise, en fonction de l'index, car elle doit être dessinée.

Autres conseils

Je ne connais aucun moyen de charger plusieurs chaînes de manière atomique, mais vous pouvez procéder de différentes manières pour rendre le processus plus efficace:

  • Appelez CComboBox :: InitStorage avant d'ajouter des éléments pour préallouer de la mémoire
  • Utilisez InsertString au lieu de AddString pour empêcher le déclenchement d'un tri sur chaque addition (en supposant que le style CBS_SORT soit activé)

Peut-être plus rapidement que CComboBox avec DrawItem serait un propriétaire données CListCtrl . Cela servirait également votre objectif de dupliquer un sous-ensemble d'éléments dans d'autres listes, car une source de données commune pourrait être utilisée.

Je suggère cela, car une CComboBox de 1 000 éléments ne sera pas très utilisable.

Je vais envisager d'utiliser une liste de sélection au lieu d'une liste déroulante pour améliorer les performances.

Une règle générale pour améliorer les performances lors de l'insertion de nombreux éléments dans une liste d'interface utilisateur est d'appeler avant l'insertion et de le redéfinir sur true après.

Voici la syntaxe correcte

#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 );
}

EDIT: améliorer la solution pour inclure la suggestion smacl

J'ai eu ce problème et je l'ai résolu de deux manières, en fonction du nombre d'éléments. Le réglage pour ne pas dessiner et le stockage initial ne faisait aucune différence pour moi. Faire un tirage propriétaire est également viable, mais j'ai eu une tonne de combobox. En supposant qu'une liste fixe pour chaque liste déroulante ne modifie pas le contenu, la liste est définie une fois.

Très grand nombre d'éléments: La combo était simplement simple / désactivée avec SetWindowText pour définir la chaîne initiale, et un petit bouton à côté ouvrait une boîte de dialogue vous permettant de choisir l'élément dans un contrôle de liste en mode Rapport des données qui auraient été dans la combo. boîte de dialogue (n'importe quoi dans la boîte de dialogue).

Moderate # Items: Création d'une classe combobox dérivée personnalisée qui remplace AddString, SelectString et gère OnDropDown. Lorsque vous ajoutez des éléments, il les place dans un vecteur temporaire, puis sur SelectString (peut également effectuer un remplacement par SetCurSel), il ajoute un élément trouvé et sélectionné. Lors de la navigation, la liste déroulante est réinitialisée et tous les éléments sont ajoutés et le élément sélectionné est sélectionné. Il y a un léger ralentissement lors de la suppression de la liste déroulante, mais vous ne le remarquez pas en petites quantités.

Les dialogues se chargent beaucoup plus rapidement et restent entièrement fonctionnels sans dessin par le propriétaire.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top