2012-10-31 84 views
16

我想這樣做,但是,列表框會在每次刪除時發生變化,所以即使我試圖做一個新對象,它也會拋出運行時異常。從列表框中刪除選定的項目

我想是這樣的:

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

回答

28

同時,通過它迭代(使用foreach)您不能修改的集合。相反,使用反向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"); 

使用反向循環確保你不取出之後,跳過所有。

+2

是的,就是這樣!謝謝! 只是一個小小的更正: for(int i = selectedItems.Count - 1; i> = 0; ** i - **) – Cristo

+0

哎呀,好眼睛,謝謝! –

+0

如果一個項目在項目列表中存在兩次,並且只有第二個項目被選中,那麼可能會有一個小錯誤。我認爲第一個可能會被刪除。 Items.RemoveAt(i)的解決方案可能稍好一些。但是將迭代逆轉也更重要! – Pieter21

6
selectedItems = lstClientes.SelectedItems; 

此行不會創建一個新的集合,而是設置爲一個ListBox中的一個參考。因此,您正在遍歷一個集合並嘗試一次從其中刪除項目。這是不可能的

您可以使用此功能,例如:

foreach (string s in lstClientes.SelectedItems.OfType<string>().ToList()) 
    lstClientes.Items.Remove(s); 
+0

對不起,沒有編譯我 – Cristo

+1

@CristobalDeIncógnitoFlipo你可能需要添加'使用系統。 Linq;'到你使用的列表中,因爲這段代碼使用LINQ來對象 – horgh

+0

我的不好。我不知道linq。這個也可以工作^^ – Cristo

6

簡單的就像這樣:

while (lst.SelectedItems.Count > 0) 
{ 
    lst.Items.Remove(lst.SelectedItems[0]); 
} 
+0

這是殘酷的,但對於小N工作正常。這些答案仍然錯過任何優雅的東西 - 這可能是一些LINQ技巧來提取索引和「反轉」迭代器(一些「ToArray」,然後一些魔術...... )。那麼,我害怕反向只能使用.NET 4.5:http://msdn.microsoft.com/pl-pl/library/bb358497%28v=vs.110%29.aspx –

1

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

 if (listBoxIn.SelectedItems.Count != 0) 
     { 
      while (listBoxIn.SelectedIndex!=-1) 
      { 
       listBoxIn.Items.RemoveAt(listBoxIn.SelectedIndex);     
      } 
     } 
+1

歡迎使用堆棧溢出!代碼只有答案在這裏幾乎總是過於簡單。給你的答案一些背景。在這種情況下,由於問題非常古老,因此值得指出爲什麼您的答案會爲已接受的最新答案增加額外的內容。 –

2
lst.Items.Remove(lst.Items[lst.SelectedIndex]); 

你可以使用這個,如果你不想循環

注意:這隻能刪除1項(多項選擇它只會刪除第一個選擇項)

0

這是最簡單的方法來刪除選定的項目

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

我不能相信這個答案是正確的。每當從列表中刪除某個項目時,SelectedItems列表是否會更改?在這種情況下,當您到達要移除的V-1項目時,所選項目列表將只有一個項目,而不是V項目。上面的答案,你總是從SelectedItems列表中刪除第零個項目是正確的。 –

+0

如果某人選擇了多個項目會怎麼樣? –

1

我遇到了同樣的問題米今天想要的東西有點清潔,以及與此LINQ的解決方案提出了:

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

基本上一樣向後迭代和刪除所選項目的帕特里克的解決方案。然而,不是向後迭代,而是反轉要刪除和迭代轉發的項目列表。我們不再遍歷原始枚舉,因此我們被允許刪除foreach中的項目。

0

創建一個全局變量:

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