Performance DataGridView.Rows.Remove

Résolu
blq Messages postés 97 Date d'inscription vendredi 22 octobre 1999 Statut Membre Dernière intervention 13 juin 2016 - 17 janv. 2012 à 15:34
blq Messages postés 97 Date d'inscription vendredi 22 octobre 1999 Statut Membre Dernière intervention 13 juin 2016 - 31 janv. 2012 à 22:45
Bonjour,

Depuis VB.net 2010, je supprime des lignes d'un DataGridView, rien d'extraordinaire, sauf que c'est très lent... Je n'arrive pas à comprendre la raison de cette lenteur, surtout que j'ai trouvé une solution plus rapide, mais qui me semble pas en accord avec une suppression directe.

Voici le code original :

' Boucle sur les lignes du DataGridView
For ctRow As Integer = 0 To DataGridView1.RowCount - 1
    ' Si le premier caractère de la première cellule ne commence pas par C
    If DataGridView1.Rows(ctRow).Cells(0).Value.ToString.StartsWith("C") = False Then
        ' Alors suppression de la ligne
        Call DataGridView1.Rows.Remove(DataGridView1.Rows(ctRow))
    End If
Next


Ce code fonctionne, mais sur un tableau de 500 lignes, chauqe suppression dure beaucoup trop longtemps...
J'ai ajouté un Call Call DataGridView1.Refresh() juste pour bien vérifier que chaque ligne en partant de la fin était supprimé.

A défautr d'avoir trouvé l'explication de cette lenteur et d'accélerer cette suppression, j'ai opté pour une solution différente, mais qui se déroule très bien, donc sans lenteur !


J'ajoute chaque ligne trouvée dans un tableau à une Collection déclarée :
Dim theList As New Collection()
' ...
' Dans la boucle sur les Rows du DataGridView, comme au-dessus, je teste le premier caractère
If DataGridView1.Rows(ctRow).Cells(0).Value.ToString.StartsWith("C") = True Then
    Dim theLine(DataGridView1.ColumnCount - 1) as String

     Conservation de chaque Cellule
    For ctCell As Integer = 0 To DataGridView1.Rows(ctRow).Cells.Count - 1
        theLine(ctCell) = DataGridView1.Rows(ctRow).Cells(ctCell).Value.ToString
    Next

    Call theList.Add(theLine)
End If

' Ensuite je vide le tableau
Call DataGridView1.Rows.Clear()

' Je remplie le tableau avec le résultat du filtre
For Each theLine() As String In theList 
    Call DataGridView1.Rows.Add(theLine)
Next



Bref, j'ai répondu à mon problème, mais peut-être que quelqu'un pourra m'indiquer la raison de la lenteur de la première écriture via Rows.Remove() qui est plus courte en écriture de code.

Coté test de perf, j'ai même supprimé le filtre.

' Boucle sur les lignes du DataGridView
For ctRow As Integer = 0 To DataGridView1.RowCount - 1
        ' suppression de la ligne
        Call DataGridView1.Rows.Remove(DataGridView1.Rows(ctRow))
Next


Même en bouclant tout simplement sur les lignes et en supprimant chaque ligne, cela reste lent tout de même...

Merci d'avance pour votre aide
A voir également:

4 réponses

Renfield Messages postés 17287 Date d'inscription mercredi 2 janvier 2002 Statut Modérateur Dernière intervention 27 septembre 2021 74
18 janv. 2012 à 06:53
tentes un SuspendLayout / ResumeLayout avant/apres ton traitement

ça evitera au controle d'etre redessiné a chaque suppression

Renfield - Admin CodeS-SourceS - MVP Visual Basic & Spécialiste des RegExp
3
blq Messages postés 97 Date d'inscription vendredi 22 octobre 1999 Statut Membre Dernière intervention 13 juin 2016 1
22 janv. 2012 à 20:15
Merci pour ce retour ! Je vais tester cela.
3
blq Messages postés 97 Date d'inscription vendredi 22 octobre 1999 Statut Membre Dernière intervention 13 juin 2016 1
31 janv. 2012 à 17:35
Après divers tests SuspendLayout() et ResumeLayout() n'apporte pas plus de performance sur le temps de traitement, meme en utilisant RemoveAt(). J'ai essayer en utilisant Refresh() avant et après, en mettant Visible = False avant et Visible = True après la suppression massive : Rien à faire. Et sur des milliers de lignes c'est pire.

Le plus rapide reste d'ajouter toutes les lignes à conserver dans un tableau temporaire, de vider complétement le DataGridView et de le remplir avec le contenu du tableau temporaire.
3
blq Messages postés 97 Date d'inscription vendredi 22 octobre 1999 Statut Membre Dernière intervention 13 juin 2016 1
31 janv. 2012 à 22:45
Finalement, je crois que j'ai trouvé la réponse... il suffisait de chercher dans l'aide !

Meilleures pratiques pour la mise à l'échelle du contrôle DataGridView Windows Forms

[...]
Les lignes, colonnes et en-tête peuvent être automatiquement redimensionnées, à mesure que le contenu de la cellule change, pour que le contenu des cellules soit visible, sans être tronqué.
Changer de mode de redimensionnement permet également de redimensionner les lignes, les colonnes et les en-têtes.
Pour déterminer la taille appropriée, le contrôle DataGridView doit examiner la valeur de chaque cellule qu'il doit prendre en compte.
Lorsque vous travaillez avec de grandes quantités de données, cette analyse peut affecter négativement les performances du contrôle lors du redimensionnement automatique.
[...]


La création des colonnes était faite dynamiquement dans mon code par une fonction générique, qui positionnait la valeur AutoSizeMode de la colonne à DataGridViewAutoSizeColumnMode.AllCells.

Bref à chaque suppression (mais aussi ajout), le tableau cherche à redimensionner chaque colonne en fonction du contenu. Quand il s'agit de quelques colonnes et quelques dizaines de lignes, cela passait inaperçu, mais dés qu'il s'agit de traiter plusieurs milliers de lignes, le temps s'écoulait en minutes...

J'espère que ma mésaventure servira à d'autres
3
Rejoignez-nous