简体   繁体   中英

C# removing items from listbox

I have a listbox being populated from a SQLDATA pull, and it pulls down some columns that i dont want like OBJECT_dfj, OBJECT_daskd. The key is all of these being with OBJECT_, is there a way to remove these from the listbox? I cannot change my SQL statement.

i tried this:

 foreach (string item in listBox1.Items)
 {
     string removelistitem = "OBJECT";
     if(item.Contains(removelistitem))
     {
         listBox1.Items.Remove(item);
     }
 }

but it gave me the error:

List that this enumerator is bound to has been modified. An enumerator can only be used if the list does not change.

You can't use an enumerator, you have to loop using an index, starting at the last item:

for (int n = listBox1.Items.Count - 1; n >= 0; --n)
{
    string removelistitem = "OBJECT";
    if (listBox1.Items[n].ToString().Contains(removelistitem))
    {
        listBox1.Items.RemoveAt(n);
    }
}

You can't modify the references in an enumerator whilst you enumerate over it; you must keep track of the ones to remove then remove them.

This is an example of the work around:

List<string> listbox = new List<string>();
List<object> toRemove = new List<object>();

foreach (string item in listbox)
{
    string removelistitem = "OBJECT";
    if (item.Contains(removelistitem))
    {
        toRemove.Add(item);
    }
}

foreach (string item in toRemove)
{
    listbox.Remove(item);
}

But if you're using c#3.5, you could say something like this.

listbox.Items = listbox.Items.Select(n => !n.Contains("OBJECT"));

You want to iterate backwards through using a counter instead of foreach. If you iterate forwards you have to adjust the counter as you delete items.

for(int i=listBox1.Items.Count - 1; i > -1; i--) {
{
    if(listBox1.Items[i].Contains("OBJECT"))
    {
        listBox1.Items.RemoveAt(i);
    }
}

You can try this also, if you don't want to deal with the enumerator:

object ItemToDelete = null;
foreach (object lsbItem in listbox1.Items)
{
   if (lsbItem.ToString() == "-ITEM-")
   {
      ItemToDelete = lsbItem;                                  
   }
}

if (ItemToDelete != null)
    listbox1.Items.Remove(ItemToDelete);

The error you are getting means that

foreach (string item in listBox1.Items)

should be replaced with

for(int i = 0; i < listBox1.Items.Count; i++) {
    string item = (string)listBox1.Items[i];

In other words, don't use a foreach.

EDIT: Added cast to string in code above

EDIT2: Since you are using RemoveAt(), remember that your index for the next iteration (variable i in the example above) should not increment (since you just deleted it).

You can't modify a collection while you're iterating over it with foreach. You might try using a regular for() statement.

You may need to iterate backwards from the end of the collection to make sure you cover every item in the collection and don't accidentally overrun the end of the collection after removing an item (since the length would change). I can't remember if .NET accounts for that possibility or not.

The problem here is that you're changing your enumerator as you remove items from the list. This isn't valid with a 'foreach' loop. But just about any other type of loop will be OK.

So you could try something like this:

for(int i=0; i < listBox1.Items.Count; )
{
    string removelistitem = "OBJECT";
    if(listBox1.Items[i].Contains(removelistitem))
         listBox1.Items.Remove(item);
    else
        ++i;
}

You could try this method:

List<string> temp = new List<string>();

    foreach (string item in listBox1.Items)
    {
        string removelistitem = "OBJECT";
        if(item.Contains(removelistitem))
        {
            temp.Items.Add(item);
         }
     }

    foreach(string item in temp)
    {
       listBox1.Items.Remove(item);
    }

This should be correct as it simply copies the contents to a temporary list which is then used to delete it from the ListBox.

Everyone else please feel free to mention corrections as i'm not 100% sure it's completely correct, i used it a long time ago.

Sorry guys i had to adjust the string

sqldatapull = dr[0].ToString();
                if (sqldatapull.StartsWith("OBJECT"))
                {
                    sqldatapull = "";
                }
                listBox1.Items.Add(sqldatapull);
                for (int i = listBox1.Items.Count - 1; i >= 0; i--)
                {
                    if (String.IsNullOrEmpty(listBox1.Items[i] as String))
                        listBox1.Items.RemoveAt(i);
                }
            }

Your question implies that you're willing to modify other parts of the code, even though you can't modify the SQL Statement itself. Instead of removing them from the ListBox Collection, it might be easier to just exclude them in the first place. This code assumes you're connecting to SQL Server:

void PopulateListBox(ListBox listToPopulate)
{
    SqlConnection conn = new SqlConnection("myConnectionString"); 
    SqlCommand cmd = new SqlCommand("spMyStoredProc", conn);
    cmd.CommandType = CommandType.StoredProcedure;
    SqlDataReader reader = cmd.ExecuteReader();
    while (reader.Read())
    {
        string item = reader.GetString(0); //or whatever column is displayed in the list
        if (!item.Contains("OBJECT_"))
            listToPopulate.Items.Add(item); 
    }
}

But if you're absolutely determined to do it this way you should check out this question on modifying an enumerable collection while iterating through it .

With this code you can remove every item from your listbox ... Notice that you should write this code in the click event of your button :

        if (listBox1.SelectedIndex != -1)
        {
            listBox1.Items.RemoveAt(listBox1.SelectedIndex);
        } 

你可以使用Linq在一行中完成

listBox1.Cast<ListItem>().Where(p=>p.Text.Contains("OBJECT")).ToList().ForEach(listBox1.Items.Remove);

I found out the hard way that if your listbox items are assigned via a data source

List<String> workTables = hhsdbutils.GetWorkTableNames();
listBoxWork.DataSource = workTables;

...you have to unbind that before doing the removal:

listBoxWork.DataSource = null;
for (int i = listBoxWork.Items.Count - 1; i >= 0; --i)
{
    if (listBoxWork.Items[i].ToString().Contains(listboxVal))
    {
        listBoxWork.Items.RemoveAt(i);
    }
}

Without the " listBoxWork.DataSource = null; " line, I was getting, " Value does not fall within the expected range "

protected void lbAddtoDestination_Click(object sender, EventArgs e)
        {
            AddRemoveItemsListBox(lstSourceSkills, lstDestinationSkills);
        }
        protected void lbRemovefromDestination_Click(object sender, EventArgs e)
        {
            AddRemoveItemsListBox(lstDestinationSkills, lstSourceSkills);
        }
        private void AddRemoveItemsListBox(ListBox source, ListBox destination)
        {
            List<ListItem> toBeRemoved = new List<ListItem>();
            foreach (ListItem item in source.Items)
            {
                if (item.Selected)
                {
                    toBeRemoved.Add(item);
                    destination.Items.Add(item);
                }
            }
            foreach (ListItem item in toBeRemoved) source.Items.Remove(item);
        }

You can use following code too:

 foreach (var item in listBox1.Items.Cast<string>().ToList())
 {
     string removelistitem = "OBJECT";
     if (item.Contains(removelistitem))
     {
        listBox1.Items.Remove(item);
     }
 }
   for (int i = 0; i < listBox1.Items.Count; i++)
    {
        if (textBox1.Text == listBox1.Items[i].ToString())
        {
            jeElement = true;
            break;
        }
    }
    if (jeElement)
    {
        label1.Text = "je element";
    }
    else
    {
        label1.Text = "ni element";
    }
    textBox1.ResetText();
    textBox1.Focus();

}

private void Form1_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Alt == true && e.KeyCode == Keys.A)
    {
        buttonCheck.PerformClick();
    }
}

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM