2009-06-27 4 views
2

Je crée un tableau de ListViewItems sur un thread d'arrière-plan, puis je le remplis avec le thread ui. Le problème est que si le tableau est trop grand, l'interface utilisateur bloque pendant que la liste est mise à jour.Comment remplir listview avec beaucoup d'informations sans bloquer?

Existe-t-il un moyen de peupler la liste avec un petit impact sur l'interface utilisateur?

+0

Winforms ou WPF? –

Répondre

8

Si vous disposez de beaucoup de données, vous pouvez l'utiliser en mode virtuel en définissant la propriété VirtualMode du contrôle ListView sur true. Cela signifie que le ListView ne sera pas peuplé dans le sens traditionnel, mais vous connecterez des gestionnaires d'événements où vous livrerez l'information à la vue de liste en petits morceaux pendant que les éléments sont affichés.

exemple très simple:

private List<string> _listViewData = new List<string>(); 
private void toolStripButton1_Click(object sender, EventArgs e) 
{ 
    _listViewData = GetData(); // fetch the data that will show in the list view 
    listView1.VirtualListSize = _listViewData.Count; // set the list size 
} 
// event handler for the RetrieveVirtualItem event 
private void listView_RetrieveVirtualItem(object sender, RetrieveVirtualItemEventArgs e) 
{ 
    if (e.ItemIndex >= 0 && e.ItemIndex < _listViewData.Count) 
    { 
     e.Item = new ListViewItem(_listViewData[e.ItemIndex]); 
    } 
} 

Vous devriez également regarder dans l'événement CacheVirtualItems.

0

Vous pouvez également utiliser des méthodes BeginUpdate et EndUpdate

listView1.BeginUpdate(); 
    //Add Values 
    listView1.EndUpdate(); 
0

Mes commentaires ont assez long, donc je décidé d'en faire un poste distinct.

Tout d'abord, +1 pour Fredrik Mörk, en utilisant VirtualMode est le chemin à parcourir. Cependant, vous perdez certaines fonctionnalités, par ex. colonne autosize, et le tri est plus facile à gérer vous-même.

Si c'est un problème, le remplissage d'un thread de travail peut sembler tentant. Cependant, la population aura toujours lieu dans le thread qui possède le contrôle de liste (c'est-à-dire pratiquement toujours le thread principal) .NET rend cela visible en vous forçant à utiliser (Begin)Invoke. De plus, les changements de contexte augmenteront considérablement le temps total nécessaire pour remplir tous les éléments si vous les remplissez un par un, de sorte que vous voulez remplir des morceaux (disons 50 éléments à la fois, ou mieux remplir autant que possible dans 20 millisecondes). Ajoutez à cela la synchronisation supplémentaire requise lorsque le contenu change, vous avez une solution assez complexe pour un résultat pas si stellaire.

Questions connexes