C# 从列表框中删除所选项目

C# 从列表框中删除所选项目,c#,listbox,C#,Listbox,我想这样做,但是,列表框在每次删除时都会更改,所以即使我尝试创建一个新对象,它也会引发运行时异常 我试着这样做: ListBox.SelectedObjectCollection selectedItems = new ListBox.SelectedObjectCollection(lstClientes); selectedItems = lstClientes.SelectedItems; if (lstClientes.SelectedIndex != -1) { for

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

我试着这样做:

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");
while (lst.SelectedItems.Count > 0)
{
   lst.Items.Remove(lst.SelectedItems[0]);
}
此行不创建新集合,但设置对列表框中集合的引用。因此,您正在遍历一个集合,并尝试立即从中删除项。这是不可能的

您可以使用此选项,例如:

foreach (string s in lstClientes.SelectedItems.OfType<string>().ToList())
   lstClientes.Items.Remove(s);
foreach(lstClientes.SelectedItems.OfType().ToList()中的字符串s)
l客户。项目。移除;

在迭代(使用
foreach
)集合时,不能修改该集合。相反,对循环使用反向

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");
使用反向循环可确保在删除它们后不会跳过任何循环。

简单如下:

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");
while (lst.SelectedItems.Count > 0)
{
   lst.Items.Remove(lst.SelectedItems[0]);
}

我找到了更好的解决办法

        if (listBoxIn.SelectedItems.Count != 0)
        {
            while (listBoxIn.SelectedIndex!=-1)
            {
                listBoxIn.Items.RemoveAt(listBoxIn.SelectedIndex);                  
            }
        }
如果不想循环,可以使用此选项


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

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

 for(int v=0; v<listBox1.SelectedItems.Count; v++) {
            listBox1.Items.Remove(listBox1.SelectedItems[v]);
        }

for(int v=0;v我今天遇到了同样的问题,想要更干净一点的东西,于是想出了这个Linq解决方案:

foreach (int index in myListBox.SelectedIndices.Cast<int>().Select(x => x).Reverse())
    myListBox.Items.RemoveAt(index);
foreach(myListBox中的int索引。selectedDices.Cast()。Select(x=>x.Reverse())
myListBox.Items.RemoveAt(索引);

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

创建一个全局变量:

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);

基于Patrick的回答,我倾向于使用反向索引删除,因为它保留了待删除项目的索引,而不删除相同的项目

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));
}
private void BtnDelete\u单击(对象发送者,事件参数e){
如果(listBox.SelectedIndex==-1){
返回;
}
//按相反顺序移除每个项目,以保持完整性
var selecteddinces=新列表(listBox.selecteddinces.Cast());
selectedDices.Reverse();
selectedIndices.ForEach(index=>listBox.Items.RemoveAt(index));
}

是的,就是这样!谢谢!只需要一点更正:对于(int i=selectedItems.Count-1;i>=0;i--),如果项目列表中有两个项目,并且只选择了第二个项目,则可能会出现一个小错误。我想第一个项目可能会被删除。包含Items.RemoveAt(i)的解决方案可能会稍微好一点。但更重要的是要反转迭代!很抱歉,没有为您编译me@CristobalDeIncógnitoflip您可能需要将
using System.Linq;
添加到您的using列表中,因为此代码使用Linqobjects@CristobalDeInc奥格尼托夫利波也许,你选择的答案是,比如说,更加节俭,因为它不会创建任何额外的集合。然而,LINQ通常比简单循环更有用、更快速。我希望尽快尝试使用LINQ;语法对我来说现在太奇怪了。因此,我习惯于选择更简单的、完全只是c#版本,忠实于保持简单的原则和我更了解的内容。我不会这么做我的想法是,简单循环通常会更快。无论如何,这次速度不是问题……但我喜欢优化。我真的很感激有两个有效的选择,如果列表中的数据增加,也许有一天会进行速度测试。再次感谢。这很残酷,但对小N来说效果不错。这些答案仍然遗漏了任何非常优雅的东西-哪一个是我的答案ght使用了一些LINQ技巧来提取索引并“反转”迭代器(一些
ToArray
,然后是一些魔术…)。嗯,恐怕只有.NET 4.5才有反向功能:欢迎使用堆栈溢出!这里只使用代码的答案几乎总是太简短。请为您的答案提供一些上下文。在这种情况下,由于问题非常古老,值得指出的是,为什么您的答案会在已接受的向上投票的答案之外添加一些内容。我不敢相信这个答案是正确的。Wo每次从列表中删除一个项目时,SelectedItems列表不是都会更改吗?在这种情况下,当您转到要删除的V-1项目时,SelectedItems列表将只有一个项目,而不是V个项目。上面的答案是正确的,您总是从SelectedItems列表中删除第0个项目。如果有人选择了多个items?这是最好的答案。SelectedDice似乎是获取所有选定项目的最方便的方式。