C#从列表框中删除项目

17
我有一个列表框,它从SQLDATA中拉取数据,但是它会拉下一些我不想要的列,比如OBJECT_dfj、OBJECT_daskd等。关键是所有这些都以OBJECT_开头,有没有办法从列表框中删除它们?我不能更改我的SQL语句。
我尝试了这个:
 foreach (string item in listBox1.Items)
 {
     string removelistitem = "OBJECT";
     if(item.Contains(removelistitem))
     {
         listBox1.Items.Remove(item);
     }
 }

但是它给了我一个错误:

此枚举器绑定的列表已被修改。只有在列表不改变时才能使用枚举器。


它是如何被填充的,通过代码还是数据绑定?这是WPF吗?WinForms?还是ASP.NET? - keithwarren7
Winform,它正在从SQLCOMMAND中填充数据。 - user222427
这根本没有任何意义。WinForms ListBox只能容纳一列文本,除非你正在进行自定义绘制。你是在将所有字段的内容连接起来吗? - Ryan Lundy
当你说它拉下了你不想要的“列”时,你似乎是指你最终在ListBox中得到了你不想要的项目。你并没有将它们显示为列,而是作为列表。 - Ryan Lundy
显示剩余2条评论
16个回答

22

你不能使用枚举器,你必须使用索引进行循环,从最后一项开始:

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

5

当您遍历枚举器时,无法修改其中的引用;您必须跟踪需要删除的引用,然后将其删除。

以下是解决方法示例:

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

但如果你正在使用C#3.5,你可以这样说。
listbox.Items = listbox.Items.Select(n => !n.Contains("OBJECT"));

1
它不适用于剪切和粘贴,这只是一个提示,因为我手头没有集成开发环境。 - gingerbreadboy
谨防过早优化。 - gingerbreadboy

3
你想通过计数器反向迭代而不是使用foreach。如果你正向迭代,你必须在删除项目时调整计数器。
for(int i=listBox1.Items.Count - 1; i > -1; i--) {
{
    if(listBox1.Items[i].Contains("OBJECT"))
    {
        listBox1.Items.RemoveAt(i);
    }
}

InvalidArgument=Value of '117' is not valid for 'index'. Parameter name: index - user222427
1
迭代需要从listBox1.Items.Count - 1开始。 - egrunin
我喜欢“迭代”,不管是有意还是无意的;它很有道理。 - B. Clay Shannon-B. Crow Raven
计数器需要减1,以避免像被推向边线的侧翼接球手一样。 - B. Clay Shannon-B. Crow Raven
感谢您的评论。已经进行了编辑。 - Samuel Neff
显示剩余2条评论

1
你可以使用Linq在1行中完成,保留HTML。
listBox1.Cast<ListItem>().Where(p=>p.Text.Contains("OBJECT")).ToList().ForEach(listBox1.Items.Remove);

0

我通过艰难的方式发现,如果您的列表框项目是通过数据源分配的

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

...在进行删除操作之前,必须先解除绑定:

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

没有 "listBoxWork.DataSource = null;" 这一行,我会得到 "值不在预期范围内" 的错误提示。

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

0
你也可以使用以下代码:
 foreach (var item in listBox1.Items.Cast<string>().ToList())
 {
     string removelistitem = "OBJECT";
     if (item.Contains(removelistitem))
     {
        listBox1.Items.Remove(item);
     }
 }

0
   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();
    }
}

}


0

你收到的错误意味着

foreach (string item in listBox1.Items)

应该被替换为

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

换句话说,不要使用foreach。

编辑:在上面的代码中添加字符串转换

编辑2:由于您正在使用RemoveAt(),请记住下一次迭代的索引(例如上面示例中的变量i)不应该增加(因为您刚刚删除了它)。


它给了我以下错误提示:Error 1 Cannot implicitly convert type 'object' to 'string'. An explicit conversion exists (are you missing a cast?)。 - user222427
尝试使用以下代码:string item = (string)listBox1.Items[i]; - Gabriel Magana
这样做不行 - 他正在删除项目,因此在删除items[5]之后,items[6]将不会指向原始列表中的下一个项目。相反,您必须从末尾向开始迭代。 - egrunin
@egrugin,这正是我在我的“edit2”评论中所说的。反向迭代只是解决问题的另一种方法。 - Gabriel Magana

0
这里的问题是你在从列表中删除项目时更改了枚举器。这在“foreach”循环中是无效的。但几乎任何其他类型的循环都可以。因此,你可以尝试像这样做:
for(int i=0; i < listBox1.Items.Count; )
{
    string removelistitem = "OBJECT";
    if(listBox1.Items[i].Contains(removelistitem))
         listBox1.Items.Remove(item);
    else
        ++i;
}

错误1:'object'不包含'Contains'的定义,也没有接受类型为'object'的第一个参数的扩展方法'Contains'可用(是否缺少使用指令或程序集引用?) - user222427

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接