IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

InvalidOperationException avec une listview


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Avatar de Spidermeu
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2006
    Messages
    147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2006
    Messages : 147
    Par défaut InvalidOperationException avec une listview
    bonjour, j'ai un problème avec la suppression d'un élément dans un listview.

    Pour résumer, j'ai une listview checkable affichant une liste (une ligne par élément). Si je souhaite supprimer une ou plusieurs lignes, je coche la case associé a la ligne et je clic sur un boutton pour les supprimer.
    Le boutton fait appel la ma méthode delete; voici le code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    private void delete()
    		{
    			int check =0;
    			int index = 0;
    			//Si des éléments sont cochés, donc à supprimer, on assigne check à 1 pour lancer la demande de suppression.
    			foreach(ListViewItem item in listView1.Items)
    			{
    				if(item.Checked ==true)
    					check=1;
    			}
    			//Si check vaut 1 alors on propose de supprimer les éléments sélectionnés
    			if(check==1)
    			{
    				if(MessageBox.Show("Supprimer  la sélection?", "Suppression...", MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) == DialogResult.Yes)
    				{
    					foreach(ListViewItem item in listView1.Items)
    					{
    						if(item.Checked == true)
    						{
    							index = listView1.Items.IndexOf(item);						
    							listView1.Items.RemoveAt(index);
    							list.RemoveAt(index);	
    							
    						}
    					}
    					this.Refresh();
    				}
    			}
    			txtbx_quantite.Focus();
    		}
    Sur mon PC ca fonctionne mais sur mon winCE, il me met InvalidOperationException.

    L'erreur arrive au moment il exécute le code suivant listView1.Items.RemoveAt(index); soit la suppression de la ligne dans la liste listview.

    Avez vous une idée du problème ?

    Merci d'avance

  2. #2
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    1. On ne peut pas modifier une collection pendant qu'elle est énumérée (foreach). (d'ailleurs ça me surprend que ça fonctionne sur ton PC...). Tu peux utiliser un for à la place, ou encore passer par une autre collection qui stocke les éléments à supprimer.
    2. Pas génial (en termes de performances) de faire un IndexOf dans un foreach... ça a une complexité O(n²), pas terrible si la liste est longue. Dans un cas comme ça un for est plus approprié, puisque ça te donne immédiatement l'index, et que l'élément correspondant est accessible en O(1). Par contre, attention : quand tu supprimes un item, ça diminue de 1 les index des items suivants.

    Tu peux faire quelque chose comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    for(int i=0; i<listView1.Items.Count; i++)
    {
        ListViewItem item = listView1.Items[i];
        if(item.Checked == true)
        {
            listView1.Items.RemoveAt(i);
            list.RemoveAt(i);
            i--;
        }
    }
    (note le i-- quand on supprime un élément)

  3. #3
    Membre confirmé
    Avatar de Spidermeu
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2006
    Messages
    147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2006
    Messages : 147
    Par défaut
    Ca fonctionne parfaitement, merci.

    Par contre, je ne comprend pas pourquoi ca ne fonctionne pas ...
    as tu de la doc pour m'expliquer pourquoi ?

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Par défaut
    Tout d'abord, il faut savoir qu'à la compilation, un foreach est transformé en l'utilisation d'un énumérateur sur la collection. Par exemple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    foreach(object o in collection)
    {
        // faire quelque chose avec o
    }
    Devient quelque chose dans ce gout là :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    IEnumerator e = collection.GetEnumerator();
    while (e.MoveNext())
    {
        object o = e.Current;
        // faire quelque chose
    }
    Hors la doc dit qu'un énumérateur n'est plus valide quand la collection est modifiée :
    http://msdn.microsoft.com/fr-fr/libr....movenext.aspx
    Citation Envoyé par MSDN
    Un énumérateur reste valide tant que la collection demeure inchangée. Si la collection est modifiée en ajoutant, modifiant ou supprimant des éléments, l'énumérateur devient irrévocablement non valide et le prochain appel à MoveNext ou à Reset lève InvalidOperationException.
    Donc, il ne faut pas modifier une collection que tu es en train d'énumérer dans un foreach...

  5. #5
    Membre confirmé
    Avatar de Spidermeu
    Homme Profil pro
    Ingénieur systèmes et réseaux
    Inscrit en
    Février 2006
    Messages
    147
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur systèmes et réseaux
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Février 2006
    Messages : 147
    Par défaut
    j'ai compris merci pour tout.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Affichage de données avec une ListView
    Par alen22 dans le forum Composants graphiques
    Réponses: 3
    Dernier message: 05/08/2012, 05h07
  2. Problème remplissage hauteur avec une ListView et style des cellules
    Par Takumi dans le forum Windows Presentation Foundation
    Réponses: 4
    Dernier message: 20/07/2010, 11h42
  3. modification avec une listview sur une BD Sqlserver
    Par k_boy dans le forum Windows Forms
    Réponses: 1
    Dernier message: 15/07/2009, 19h57
  4. Touche "entrée" avec une listview
    Par chrisviper dans le forum IHM
    Réponses: 9
    Dernier message: 22/01/2008, 22h25
  5. Problèmes avec une Listview
    Par janego dans le forum C++Builder
    Réponses: 1
    Dernier message: 10/07/2006, 19h27

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo