-1

i have a listbox and i want to delete an object in collection with this listbox . but i can only just delete the first item (select index 0 ) why ?? i can't solve this problem

private void removeButton_Click(object sender, EventArgs e)
{
    foreach (Student element in studentCollection) {

        if (studentListbox.SelectedIndex != -1 && element.Name == studentListbox.SelectedItem.ToString())
        {
            studentCollection.Remove(element);
            studentListbox.Items.RemoveAt(studentListbox.SelectedIndex);
        }
        break;
    }
}
derloopkat
  • 6,232
  • 16
  • 38
  • 45
amir mehr
  • 75
  • 1
  • 9
  • 2
    One thing to note is that you can't remove an item from `studentCollection` inside the foreach loop that is iterating through it. – St. Pat Apr 03 '18 at 19:27
  • so how can i delete an item from collection ? and also if i can't remove from foreach loop why i can remove first item ? – amir mehr Apr 03 '18 at 19:30
  • the foreach loop doesn't like it when the collection is changed while it is working with it. A for loop wouldn't mind, but you would have to keep track of the index. Another option is to use the loop to find the item, save the index or object reference, and remove after breaking the loop. – St. Pat Apr 03 '18 at 19:34
  • You for-loop it instead. If you using a BindingList instead and have the ListBox use the BindingList as a DataSource, you would only have to remove the items from the source only. – LarsTech Apr 03 '18 at 19:35
  • See https://stackoverflow.com/questions/759966/what-is-the-best-way-to-modify-a-list-in-a-foreach-loop – Steve Apr 03 '18 at 19:36

2 Answers2

0

Use a For loop instead of a foreach loop. Foreach loop can't work because the number of item in your collection will keep changing.

Something like this:

private void removeButton_Click(object sender, EventArgs e)
{
        student element;
        for (int i = 0; i < studentCollection.items.count; i++)
        {
            element = studentCollection[i];
            //Remove your item here
        }
}
Maxter
  • 716
  • 7
  • 15
  • 2
    Better break out of that loop or iterate backwards to avoid errors. – LarsTech Apr 03 '18 at 19:35
  • if i use for loop then how can i find listbox selected item name in studentCollection ? – amir mehr Apr 03 '18 at 19:43
  • I edited my answer. You define "element" before the loop. Then you can find the name like this: name = element.Name or simply: studentCollection[i].Name – Maxter Apr 03 '18 at 19:51
  • yes this code worked too I was not paying attention that i can use this : element = studentCollection[i]; :) – amir mehr Apr 03 '18 at 19:59
0
var index = studentListbox.SelectedIndex;
if (index != -1)
{
    var student = studentCollection.First(s => s.Name == studentListbox.SelectedValue.ToString());
    studentCollection.remove(student);
    studentListbox.Items.RemoveAt(index);
}

Is all you really need to write.

First grab the index to reduce duplication and potential errors.

Then we use the LINQ first method to locate the student.

Then we remove the student.

Finally we remove the associated list item.

Aluan Haddad
  • 29,886
  • 8
  • 72
  • 84
  • i try it but it gives a InvalidOperationException – amir mehr Apr 03 '18 at 19:47
  • @amirmehr I forgot the to string, that's probably why. I assume you're getting the exception on the call to First? – Aluan Haddad Apr 03 '18 at 19:49
  • yeah it worked :) i change this line : var student = studentCollection.First(element => element.Name == studentListbox.SelectedItem.ToString()); but i can't work with LINQ i should to learn it – amir mehr Apr 03 '18 at 19:52
  • @amirmehr there's nothing to it, if you can understand what that line does then you're halfway there. And yes, you absolutely must learn it. If you say you know the language it's assumed you know Linq. It's axiomatic – Aluan Haddad Apr 03 '18 at 19:53
  • @amirmehr what makes the other answer better? This is simpler and easier to maintain – Aluan Haddad Apr 03 '18 at 20:01