23

我想这样做,但是列表框在每次删除时都会更改,因此即使我尝试创建一个新对象,它也会引发运行时异常。

我试过这样:

ListBox.SelectedObjectCollection selectedItems = new ListBox.SelectedObjectCollection(lstClientes);
   selectedItems = lstClientes.SelectedItems;
if (lstClientes.SelectedIndex != -1)
{ 
    foreach (string s in selectedItems)
        lstClientes.Items.Remove(s);
}
else
    MessageBox.Show("Debe seleccionar un email");
4

9 回答 9

41

foreach迭代(使用 a )通过它时,您不能修改集合。而是使用反向for循环:

ListBox.SelectedObjectCollection selectedItems = new ListBox.SelectedObjectCollection(lstClientes);
selectedItems = lstClientes.SelectedItems;

if (lstClientes.SelectedIndex != -1)
{ 
    for (int i = selectedItems.Count - 1; i >= 0; i--)
        lstClientes.Items.Remove(selectedItems[i]);
}
else
    MessageBox.Show("Debe seleccionar un email");

使用反向循环可确保您在删除它们后不会跳过任何内容。

于 2012-10-31T00:24:14.680 回答
9
selectedItems = lstClientes.SelectedItems;

此行不会创建新集合,而是设置对列表框中的集合的引用。因此,您正在遍历一个集合并尝试立即从中删除项目。这不可能

您可以使用它,例如:

foreach (string s in lstClientes.SelectedItems.OfType<string>().ToList())
   lstClientes.Items.Remove(s);
于 2012-10-31T00:21:56.787 回答
6

就像这样简单:

while (lst.SelectedItems.Count > 0)
{
   lst.Items.Remove(lst.SelectedItems[0]);
}
于 2013-08-06T15:41:36.830 回答
5
lst.Items.Remove(lst.Items[lst.SelectedIndex]);

如果您不想循环,可以使用它

注意:这仅适用于删除 1 个项目(多选它只会删除第一个选定的项目)

于 2015-05-11T02:52:20.733 回答
2

为了建立帕特里克的回答,我倾向于使用反向索引删除,因为它保留了待删除项目的索引,而它们被删除而不删除相同的项目。

private void BtnDelete_Click(object sender, EventArgs e) {
    if (listBox.SelectedIndex == -1) {
        return;
    }

    // Remove each item in reverse order to maintain integrity
    var selectedIndices = new List<int>(listBox.SelectedIndices.Cast<int>());
    selectedIndices.Reverse();
    selectedIndices.ForEach(index => listBox.Items.RemoveAt(index));
}
于 2018-08-14T23:32:38.440 回答
1

我找到了更好的解决方案。

        if (listBoxIn.SelectedItems.Count != 0)
        {
            while (listBoxIn.SelectedIndex!=-1)
            {
                listBoxIn.Items.RemoveAt(listBoxIn.SelectedIndex);                  
            }
        }
于 2015-02-04T11:08:20.997 回答
1

我今天遇到了同样的问题,想要一些更清洁的东西,并提出了这个 Linq 解决方案:

foreach (int index in myListBox.SelectedIndices.Cast<int>().Select(x => x).Reverse())
    myListBox.Items.RemoveAt(index);

与 Patrick 的向后迭代和删除选定项目的解决方案基本相同。然而,我们不是向后迭代,而是反转要删除的项目列表并向前迭代。我们不再遍历原始枚举,因此我们可以删除 foreach 中的项目。

于 2016-01-02T06:48:26.613 回答
0

这是删除所选项目的最简单方法

 for(int v=0; v<listBox1.SelectedItems.Count; v++) {
            listBox1.Items.Remove(listBox1.SelectedItems[v]);
        }
于 2015-06-28T16:09:19.810 回答
-1

创建一个全局变量:

public partial class Form1 : Form
    {

        Int32 index;
    }

然后在选定的索引更改处将该索引保存在您定义的 var 中:

 private void lsbx_layers_SelectedIndexChanged(object sender, EventArgs e)
        {

           layerindex = lsbx_layers.SelectedIndices[0];//selected index that has fired the event
         }

最后,删除元素:

 lsbx_layers.Items.RemoveAt(Layerindex);
于 2016-05-06T09:41:32.423 回答