2010-12-03 17 views
0

J'ai une liste Array pour enregistrer les fichiers sélectionnés et un ListBox pour afficher uniquement le nom des fichiers .. mon exigence est de supprimer les fichiers correspondants de arraylist quand il est supprimé de la liste ... ici est mon code:Supprimer des fichiers de ArrayList en C#

public ArrayList to_compress = new ArrayList(); 
ListBox pack_lbx=new ListBox(); 

private void add_btn_Click(object sender, EventArgs e) 
{ 
    OpenFileDialog ofd = new OpenFileDialog(); 
    ofd.Multiselect = true; 
    if (ofd.ShowDialog() == DialogResult.OK) 
    { 
     foreach (string f in ofd.FileNames) 
     { 
      FileInfo f_inf = new FileInfo(f); 
      if (pack_lbx.Items.IndexOf(Path.GetFileName(f)) == -1) 
      { 
       to_compress.Add(new string[] { f, f_inf.Name }); 
       pack_lbx.Items.Add(Path.GetFileName(f)); 
      }     
     } 
    } 

    private void remove_btn_Click(object sender, EventArgs e) 
    { 
     // pack_lbx.Items.Remove(pack_lbx.Items); 
     ListBox.SelectedObjectCollection s = pack_lbx.SelectedItems; 
     while (s.Count > 0) 
     { 
      pack_lbx.Items.Remove(s[0]); 
      to_compress.Remove(s.ToString()); //this doesnt work 
     } 
    } 
+0

Mes yeux!!!! –

Répondre

1

Je ne vois pas de question ici. Je suppose que vous obtenez une erreur parce que vous essayez de modifier une collection que vous êtes en train de boucler activement?

Si ce n'est pas le problème, veuillez le changer en une question afin que nous puissions donner une meilleure réponse.

Cependant, en supposant que je devine juste ...

Vous ne pouvez pas le faire ... Il salit les choses si vous modifiez la liste que nous parcourons. Au lieu de cela, vous devriez créer une nouvelle liste et y ajouter des éléments (en les copiant depuis la liste que vous parcourez lorsque vous la parcourez) et en sautant simplement le code "ajouter" pour les éléments que vous voulez supprimer".

+0

ne reçois aucune erreur, j'essaie de remplir le nom des fichiers sélectionnés (pas le chemin d'accès complet) dans la liste et le nom complet (y compris le chemin) des fichiers dans ArrayList() qui prend la paire de chaîne.quand je supprime un fichier dans la liste aucun contrôle pour supprimer l'entrée correspondante dans ArrayList(). –

0
to_compress.Remove(s[0].ToString()); 
1
while (s.Count > 0) 
    { 
     pack_lbx.Items.Remove(s[0]); 
     to_compress.Remove(s.ToString());//this doesnt work 
    } 

cela ne fonctionnera pas parce que, vous objet supprimez d'une collection en boucle à travers la collection afin

faire ce

private void remove_btn_Click(object sender, EventArgs e) 
{ 
    // pack_lbx.Items.Remove(pack_lbx.Items); 
    ArrayList tempList = new ArrayList(); 
    ListBox.SelectedObjectCollection s = pack_lbx.SelectedItems; 
    foreach(string str in to_compress) 
    { 
     if(!s.Contains(str)) 
     tempList.Add(str) 
    } 

    to_compress = tempList; 

}

+0

mais s ne contient que le nom du fichier ie.leaf name et str dans to_compress stocke le nom de fichier complet. –

0

je peux » t voir toute ligne de code qui ajoute les fichiers à ArrayList to_compress.

De même, si vous ajoutez l'objet FileInfo à arraylist, vous ne pouvez pas le supprimer en utilisant le nom du fichier. Envisagez d'utiliser un dictionnaire générique avec le nom du fichier comme clé et l'objet fichier comme valeur.

 
var to_compress = new Dictionary<string,FileInfo>(); 
to_compress.Add(filename,File); 

//then you can remove by 

to_compress.Remove(filename); 

//you can loop through it like so 
foreach (var pair in to_compress) 
{ 
    string filename = pair.Key; 
    FileInfo file = pair.Value;  
} 
+0

oh ... désolé ... j'ai oublié de le décommenter ... maintenant son édition –

1

Essayer de garder deux listes identiques synchronisées est un modèle qui vous ouvre à des bogues, parce que si vous ne parvenez pas à synchroniser correctement dans un seul endroit, votre interface utilisateur sera affiche des informations qui est différent de ce que votre programme est en utilisant en interne.

Une meilleure approche consiste à ne garder qu'une seule liste "maître". Laissez le contrôle ListBox contenir la liste, manipulez-le dans le contrôle ListBox et copiez uniquement les noms de fichiers hors de ListBox à la fin du processus. Si vous voulez que le texte affiché dans la listbox soit différent de la chaîne sous-jacente (par exemple afficher les noms de feuille dans la boîte mais garder les chemins complets en interne), vous pouvez créer une classe triviale pour contenir le chemin complet et surcharger sa ToString () pour retourner le nom de la feuille. Ajoutez ensuite des instances de cette classe plutôt que des chaînes brutes à ListBox.

Si vous insistez pour conserver deux listes en synchronisation, la plus simple consiste à utiliser ListBox.SelectedIndex avec la méthode RemoveAt(), et à supprimer simplement le même élément des deux listes.

Si vous devez supprimer un élément d'une liste que vous énumérez, vous pouvez:

  • Utilisez une boucle avec un indice au lieu de foreach pour faire le itérer. Vous pouvez ensuite accéder aux éléments de la liste avec la syntaxe de l'index de tableau [i] et les supprimer avec RemoveAt (i). Faites juste attention à la façon dont vous avancez l'indice après la suppression d'un élément.
  • Utilisez une variable/liste séparée pour stocker les références aux éléments que vous souhaitez supprimer lors de votre première boucle, puis exécutez une deuxième boucle sur cette liste pour effectuer la suppression en tant qu'étape de post-traitement. La logique métier dans les événements de bouton !!!
+0

ouais .. "maître" approche de la liste est exactement ce que je voulais faire ... mais je ne sais pas comment mettre en œuvre, alors j'ai choisi cette approche.. –