Question

How can i use second method instead of first?

first (web user control)

   public void Remove()
        {

            int count = this.ListBox1.Items.Count;

            for (int i = count - 1; i > -1; i--)
            {
                if (ListBox1.Items[i].Selected)
                {
                    ListBox1.Items.Remove(ListBox1.Items[i]);
                }
            }
        }

Test.aspx(Test of first)

  protected void btnRemove_Click(object sender, EventArgs e)
        {
            ItemOrderer2.Remove();

        }

second(web user control)

 public void Remove(string value)
        {
            ListItem li = new ListItem();
            li = ListBox1.Items.FindByValue(value);
            if (li != null)
            {
                this.ListBox1.Items.Remove(li);
            }

Test.aspx( Test of Second)

  protected void btnRemove_Click(object sender, EventArgs e)
        {
           // ItemOrderer2.Remove();
            if (ItemOrderer2.Items.Count > 0)
                foreach (ListItem li in ItemOrderer2.Items)
                {
                    if (li.Selected)
                    {
                        ItemOrderer2.Remove(li.Value);
                    }
                }
        }
Was it helpful?

Solution

You can't use foreach if you are removing data inside the foreach - it (intentionally) breaks the iterator.

If for works, why change it? If you are desperate to use foreach, then build a separate list first - for example:

List<ListItem> remove = new List<ListItem>();
foreach(ListItem li in ItemOrdere2.Items) {
    if(li.Selected) remove.Add(li);
}
foreach(ListItem li in remove) {
    ItemOrderer2.Remove(li); // or similar
}

The first query can often be simplified by LINQ if if is available.

OTHER TIPS

You can get the values to be removed first to a list and then run them through the remove function. This can be further enhanced if needed.

var removedValues = ItemOrderer2.Items
                    .Where(li => li.Selected)
                    .Select(li => li.Value).ToList();

foreach (var removedValue in removedValues) {
   ItemOrderer2.Remove(removedValue);
}

You cannot modify a collection you are iterating over in a foreach loop.

That being said, it seems you are trying to remove the selected items from a ListBox. You could also use something like:

while(ItemOrderer2.SelectedItem != null)
{
    ItemOrderer2.Items.Remove(ItemOrderer2.SelectedItem);
}

Well, you can't make any changes to an IList<> with foreach, simply because it would change the number of items in it.

Also, the 1st method you showed are flawed, since count could start out as 20 but if you remove 10 items with your method, count will still be 20 and you would go out of bounds on the IList<>

Basically, if you want to remove / add stuff while iterating over it you have to do something like

for (int i = 0; i < ListBox1.Items.Count; i++)
{
   if (ListBox1.Items[i].Selected)
   {
      ListBox1.Items.RemoveAt(i)
      i--;
   }
}

Notice the i-- if you remove anything. Let's say item[2] is selected, your loop would go:

  1. if Count > 0 proceed
  2. if item[0] is selected, remove it (it's not)
  3. increment our counter
  4. if Count > 1 proceed
  5. if item[1] is selected, remove it (it's not)
  6. increment our counter
  7. if Count > 2 proceed
  8. item[2] is selected, remove it (it is)
  9. remove item[2] (now, what was previously item[3] will be item[2]
  10. decrement our counter
  11. increment our counter
  12. if Count > 2 proceed
  13. ...

Hope this helps :)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top