开发者

Deleting files from ArrayList in C#

I have an Array List to save selected 开发者_运维问答files and a ListBox to display only the name of the files..my requirement is to delete corresponding files from arraylist when its deleted from listbox...here is my code:

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 
        }
    }


I don't see a question here. I'm assuming that you're getting an error because you're trying to modify a collection that you're actively looping through?

If that's NOT the issue, please change this to a question so that we can give a better answer.

However, assuming I am guessing right...

You can't do that... It messes up things if you alter the list you're looping through.

Instead, you should be creating a NEW list and adding items to it (copying them from the list you're looping through as you're looping through it) and just skipping the "add" code for the items you want to "delete".


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

this will not work because , you are deleting object from a collection while looping through the collection so

do this

 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;

}


Trying to keep two identical lists synchronised is a pattern that opens you up to bugs, because if you fail to synchronise correctly in just one place, your UI will be displaying information that is different from what your program is using internally.

A better approach is to only keep one "master" list. Let the ListBox hold the list, manipulate it in the ListBox, and only copy the filenames out of the ListBox at the end of the process.

If you want the text displayed in the listbox to be different from the underlying string (e.g. display leafnames in the box but keep full pathnames internally) then you can create a trivial class to hold the full pathname and override its ToString() to return the leafname. Then add instances of this class rather than raw strings to the ListBox.

If you insist on keeping two lists in sync, then the easiest is to use ListBox.SelectedIndex with the RemoveAt() method, and simply remove the same item from both lists.

If you need to remove an item from a list that you are enumerating, you can either:

  • Use a for loop with an index instead of foreach to do the iterating. You can then acess list items with the array index [i] syntax, and delete them with RemoveAt(i). Just be careful with how you advance the index after deleting an item.
  • Use a separate variable/list to store references to the items you wish to delete during your first loop, and then execute a second loop over this list to actually do the deletion as a post-processing step.


to_compress.Remove(s[0].ToString());


I can't see any line of code that add the files to the ArrayList to_compress.

Also if you adding the FileInfo object to arraylist you can't remove it using the name of the file.

Consider using generic dictionary that have name of file as key and the actual file object as value.

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜