2010-01-19 22 views
11

Tengo un cuadro de lista que se rellena desde un arrastre SQLDATA, y tira hacia abajo algunas columnas que no quiero como OBJECT_dfj, OBJECT_daskd. La clave es que todos ellos están con OBJECT_, ¿hay alguna manera de eliminarlos del listbox? No puedo cambiar mi declaración SQL.C# eliminación de elementos del cuadro de lista

He intentado esto:

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

pero me dio el error:

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

+0

¿Cómo está siendo poblada, a través de código o enlace de datos? ¿Es este WPF? WinForms? ASP.NET? – keithwarren7

+0

Winform, y se completa desde un SQLCOMMAND –

+0

Esto no tiene ningún sentido. WinForms ListBox solo puede contener una columna de texto a menos que esté haciendo un dibujo personalizado. ¿Concatenan los contenidos de todos los campos, o qué? –

Respuesta

0

siento chicos que tenía que ajustar la cadena de

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

no puede modificar las referencias en un enumerador mientras enumerar sobre ella; debe realizar un seguimiento de los que debe eliminar y luego eliminarlos.

Este es un ejemplo del trabajo en torno a:

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

Pero si usted está usando C# 3.5, se podría decir algo como esto.

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

lo intentó, parece que no elimina nada –

+1

ganó No funciona como un trabajo de cortar y pegar, es una pista más que una respuesta, ya que no tengo un IDE a mano. – gingerbreadboy

+0

este método dosis no tiene un buen rendimiento, enumerar elementos de la lista dos veces ... –

0

El error que está recibiendo medios que

foreach (string item in listBox1.Items) 

debe sustituirse por

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

En otras palabras, no utilizan un foreach.

EDITAR: Añadido echó a cadena en el código de

Edit2: Puesto que usted está utilizando RemoveAt(), recuerde que su índice para la siguiente iteración (variable i en el ejemplo anterior) no deben incrementar (ya que sólo lo eliminó).

+0

me da: Error No se puede convertir implícitamente el tipo 'objeto' en 'cadena'. Existe una conversión explícita (¿falta un molde?) –

+0

try string item = (string) listBox1.Items [i]; –

+0

Esto no funcionará; está eliminando elementos, por lo tanto, después de eliminar los elementos [5], los elementos [6] no apuntarán al siguiente elemento de la lista original. En cambio, debe iterar desde el final hasta el comienzo. – egrunin

0

No puede modificar una colección mientras itera sobre ella con foreach. Puede intentar usar una declaración for() regular.

Puede necesitar iterar hacia atrás desde el final de la colección para asegurarse de cubrir cada elemento de la colección y no invadir accidentalmente el final de la colección después de eliminar un elemento (ya que la longitud podría cambiar). No recuerdo si .NET da cuenta de esa posibilidad o no.

19

No puede utilizar un enumerador, usted tiene que bucle que utiliza un índice, empezando por el último elemento:

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

El problema aquí es que usted está cambiando su empadronador como se quitan los elementos de la lista. Esto no es válido con un bucle 'foreach'. Pero casi cualquier otro tipo de bucle estará bien.

Por lo que podría intentar algo como esto:

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

Error 1 'objeto' no contiene una definición para 'Contiene' y no se puede encontrar ningún método de extensión 'Contiene' que acepte un primer argumento de tipo 'objeto' (¿falta una directiva using o una referencia de ensamblado?) –

2

¿Quieres recorrer hacia atrás por el uso de un contador en lugar de foreach. Si itera hacia adelante, debe ajustar el contador a medida que elimina elementos.

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

Error 'objeto' no contiene una definición para 'Contiene' y no se puede encontrar ningún método de extensión 'Contiene' que acepte un primer argumento de tipo 'objeto' (¿falta una directiva using o una referencia de ensamblado?) –

+0

Creo ' if (listBox1.Items [i] .Contains (removelistitem)) 'debería leer' if (((string) listBox1.Items [i]). Contiene (removelistitem)) '. –

+0

InvalidArgument = El valor de '117' no es válido para 'index'. Nombre del parámetro: índice –

0

Usted podría intentar este método:

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

Esto debe ser correcto ya que simplemente copia el contenido a una lista temporal que luego se utiliza para eliminarla del cuadro de lista.

Todos los demás pueden escribir correcciones, ya que no estoy 100% seguro de que sea completamente correcto, lo usé hace mucho tiempo.

0

Su pregunta implica que usted está dispuesto a modificar otras partes del código, a pesar de que no se puede modificar la propia instrucción SQL. En lugar de eliminarlos de la Colección ListBox, podría ser más fácil simplemente excluirlos en primer lugar. Este código se supone que se está conectando a 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); 
    } 
} 

Pero si usted está absolutamente decidido a hacerlo de esta manera que debe salir esta pregunta en modifying an enumerable collection while iterating through it.

0

Puede probar esto también, si usted no quiere tratar con el empadronador:

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

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

Con este código se puede quitar todos los elementos de su cuadro de lista ... Tenga en cuenta que usted debe escribir esto código en el evento clic del botón:

 if (listBox1.SelectedIndex != -1) 
     { 
      listBox1.Items.RemoveAt(listBox1.SelectedIndex); 
     } 
0

Usted puede hacerlo en la línea 1, mediante el uso de LINQ

listBox1.Cast<ListItem>().Where(p=>p.Text.Contains("OBJECT")).ToList().ForEach(listBox1.Items.Remove); 
0

me enteré de la manera más difícil que si los elementos de cuadro de lista se asignan a través de una fuente de datos

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

... hay que desvincular que antes de hacer la extracción:

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

Sin el "listBoxWork.DataSource = null; "la línea, yo estaba haciendo," Valor no está dentro del rango esperado "

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

yo u puede utilizar el código siguiente también:

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

}

Cuestiones relacionadas