2012-10-31 73 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を使用して)反復しながら、あなたは、コレクションを変更することはできません。あなたがそれらを削除した後に任意のをスキップしません確実に逆ループを使用して

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

:代わりに逆forループを使用します。

+2

ええ、それだけです!ありがとうございました! ちょっとした修正: for(int i = selectedItems.Count - 1; i> = 0; ** i - **) – Cristo

+0

おっと、良いアイ、ありがとう! –

+0

アイテムがアイテムリストに2回存在し、2番目のアイテムだけが選択されている場合、小さなバグが発生する可能性があります。私は最初のものが削除されるかもしれないと思う。 Items.RemoveAt(i)を使った解は少し良いかもしれません。しかし、反復を逆にすることがさらに重要になります! – Pieter21

6
selectedItems = lstClientes.SelectedItems; 

この行は、新しいコレクションを作成しませんが、リストボックス内の1への参照を設定します。

は、私はこのように試してみました。コレクションを繰り返して、一度にアイテムを削除しようとしています。それはたとえば、あなたがこれを使用することができ

ことはできません。

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

申し訳ありませんが、私のためにコンパイルしていません – Cristo

+1

@CristobalDeIncógnitoFlipoあなたはおそらく 'using Systemを追加する必要がありました。このコードはオブジェクトに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

これは私がこれと同じprobleに遭遇し、選択した項目

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

この回答が正しいとは思えません。アイテムがリストから削除されるたびに、SelectedItemsリストは変更されませんか?その場合、削除するV-1アイテムに移動すると、選択したアイテムリストにはVアイテムではなく、1つのアイテムのみが表示されます。 SelectedItemsリストから常に0番目のアイテムを削除している上記の答えは正しいです。 –

+0

複数のアイテムを選択した場合はどうなりますか? –

1

を削除する最も簡単な方法ですビットクリーンな何かをしたかったし、このLINQのソリューションを思い付いメートル今日:後方反復して選択した項目を削除するのパトリックのソリューションとして

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

基本的には同じ。しかし、逆に反復するのではなく、削除する項目のリストを逆にしてフォワードを繰り返します。元の列挙を繰り返し処理することがなくなり、foreach内のアイテムを削除することができます。

0

グローバル変数を作成します。そして、あなたが定義したVARでそのインデックスの保存選択した屈折率の変化で

public partial class Form1 : Form 
    { 

     Int32 index; 
    } 

を:

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); 
関連する問題