C# 从列表框中删除项目

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2096489/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 23:28:06  来源:igfitidea点击:

C# removing items from listbox

c#

提问by

I have a listbox being populated from a SQLDATA pull, and it pulls down some columns that i dont want like OBJECT_dfj, OBJECT_daskd. The key is all of these being with OBJECT_, is there a way to remove these from the listbox? I cannot change my SQL statement.

我有一个从 SQLDATA pull 填充的列表框,它下拉了一些我不想要的列,比如 OBJECT_dfj、OBJECT_daskd。关键是所有这些都带有 OBJECT_,有没有办法从列表框中删除这些?我无法更改我的 SQL 语句。

i tried this:

我试过这个:

 foreach (string item in listBox1.Items)
 {
     string removelistitem = "OBJECT";
     if(item.Contains(removelistitem))
     {
         listBox1.Items.Remove(item);
     }
 }

but it gave me the error:

但它给了我错误:

List that this enumerator is bound to has been modified. An enumerator can only be used if the list does not change.

此枚举器绑定到的列表已被修改。仅当列表未更改时才能使用枚举器。

采纳答案by Jamie Keeling

Sorry guys i had to adjust the string

对不起,我不得不调整字符串

sqldatapull = dr[0].ToString();
                if (sqldatapull.StartsWith("OBJECT"))
                {
                    sqldatapull = "";
                }
                listBox1.Items.Add(sqldatapull);
                for (int i = listBox1.Items.Count - 1; i >= 0; i--)
                {
                    if (String.IsNullOrEmpty(listBox1.Items[i] as String))
                        listBox1.Items.RemoveAt(i);
                }
            }

回答by gingerbreadboy

You can't modify the references in an enumerator whilst you enumerate over it; you must keep track of the ones to remove then remove them.

枚举时不能修改枚举器中的引用;您必须跟踪要删除的那些然后删除它们。

This is an example of the work around:

这是解决方法的示例:

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

But if you're using c#3.5, you could say something like this.

但是,如果您使用的是 c#3.5,则可以这样说。

listbox.Items = listbox.Items.Select(n => !n.Contains("OBJECT"));

回答by Gabriel Magana

The error you are getting means that

你得到的错误意味着

foreach (string item in listBox1.Items)

should be replaced with

应该替换为

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

In other words, don't use a foreach.

换句话说,不要使用 foreach。

EDIT: Added cast to string in code above

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

EDIT2: Since you are using RemoveAt(), remember that your index for the next iteration (variable i in the example above) should not increment (since you just deleted it).

EDIT2:由于您使用的是 RemoveAt(),请记住下一次迭代的索引(上例中的变量 i)不应增加(因为您刚刚删除了它)。

回答by David

You can't modify a collection while you're iterating over it with foreach. You might try using a regular for() statement.

在使用 foreach 迭代集合时,您无法修改集合。您可以尝试使用常规的 for() 语句。

You may need to iterate backwards from the end of the collection to make sure you cover every item in the collection and don't accidentally overrun the end of the collection after removing an item (since the length would change). I can't remember if .NET accounts for that possibility or not.

您可能需要从集合的末尾向后迭代,以确保覆盖集合中的每个项目,并且在删除项目后不会意外地超出集合的末尾(因为长度会改变)。我不记得 .NET 是否考虑了这种可能性。

回答by egrunin

You can't use an enumerator, you have to loop using an index, starting at the last item:

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

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

回答by Sam Holloway

The problem here is that you're changing your enumerator as you remove items from the list. This isn't valid with a 'foreach' loop. But just about any other type of loop will be OK.

这里的问题是,当您从列表中删除项目时,您正在更改您的枚举器。这对“foreach”循环无效。但几乎任何其他类型的循环都可以。

So you could try something like this:

所以你可以尝试这样的事情:

for(int i=0; i < listBox1.Items.Count; )
{
    string removelistitem = "OBJECT";
    if(listBox1.Items[i].Contains(removelistitem))
         listBox1.Items.Remove(item);
    else
        ++i;
}

回答by Samuel Neff

You want to iterate backwards through using a counter instead of foreach. If you iterate forwards you have to adjust the counter as you delete items.

您想通过使用计数器而不是 foreach 向后迭代。如果向前迭代,则必须在删除项目时调整计数器。

for(int i=listBox1.Items.Count - 1; i > -1; i--) {
{
    if(listBox1.Items[i].Contains("OBJECT"))
    {
        listBox1.Items.RemoveAt(i);
    }
}

回答by Jamie Keeling

You could try this method:

你可以试试这个方法:

List<string> temp = new List<string>();

    foreach (string item in listBox1.Items)
    {
        string removelistitem = "OBJECT";
        if(item.Contains(removelistitem))
        {
            temp.Items.Add(item);
         }
     }

    foreach(string item in temp)
    {
       listBox1.Items.Remove(item);
    }

This should be correct as it simply copies the contents to a temporary list which is then used to delete it from the ListBox.

这应该是正确的,因为它只是将内容复制到一个临时列表,然后用于将其从 ListBox 中删除。

Everyone else please feel free to mention corrections as i'm not 100% sure it's completely correct, i used it a long time ago.

其他人请随时提及更正,因为我不是 100% 确定它完全正确,我很久以前使用过它。

回答by Jeremy S

Your question implies that you're willing to modify other parts of the code, even though you can't modify the SQL Statement itself. Instead of removing them from the ListBox Collection, it might be easier to just exclude them in the first place. This code assumes you're connecting to SQL Server:

您的问题暗示您愿意修改代码的其他部分,即使您无法修改 SQL 语句本身。与其从 ListBox 集合中删除它们,不如首先将它们排除在外。此代码假定您正在连接到 SQL Server:

void PopulateListBox(ListBox listToPopulate)
{
    SqlConnection conn = new SqlConnection("myConnectionString"); 
    SqlCommand cmd = new SqlCommand("spMyStoredProc", conn);
    cmd.CommandType = CommandType.StoredProcedure;
    SqlDataReader reader = cmd.ExecuteReader();
    while (reader.Read())
    {
        string item = reader.GetString(0); //or whatever column is displayed in the list
        if (!item.Contains("OBJECT_"))
            listToPopulate.Items.Add(item); 
    }
}

But if you're absolutely determined to do it this way you should check out this question on modifying an enumerable collection while iterating through it.

但是,如果您绝对确定要这样做,则应该查看有关在迭代时修改可枚举集合的问题。

回答by Somebody

You can try this also, if you don't want to deal with the enumerator:

如果你不想处理枚举器,你也可以试试这个:

object ItemToDelete = null;
foreach (object lsbItem in listbox1.Items)
{
   if (lsbItem.ToString() == "-ITEM-")
   {
      ItemToDelete = lsbItem;                                  
   }
}

if (ItemToDelete != null)
    listbox1.Items.Remove(ItemToDelete);