0

I have a c# wpf listbox and I am trying to get the values from the selected items. I cannot use a foreach loop (every value I find will remove an item from the listbox). But this seems impossible.

What I want is somthing like this:

for (int i = <numberofselecteditems> - 1; i >= 0; i--)
{
    string displaymembervalue = listbox.selecteditem[i].displaymembervalue;

}

I have a solution which involve to loop over all the listbox items twice. This is not really an option since it will slow the app too much.

Like I said before, this is NOT the

System.Windows.Forms.Listbox

but the

System.Windows.Controls.Listbox

thank you!!

J.

Jan Solo
  • 183
  • 1
  • 8
  • 19
  • Sorry, what is the Q? – apomene Jun 05 '14 at 14:29
  • As a side note, assuming your ListBox only has a minimal (<100 or so) amount of items, you shouldn't see a performance hit by enumerating the items twice. However, you're right that you don't need (or want) the extra iteration. – GEEF Jun 05 '14 at 14:32
  • 1
    _every value I find will remove an item from the listbox_ - you can't iterate over list while removing items from it at the same time – Tzah Mama Jun 05 '14 at 14:35
  • @TzahMama you can if you are using a for loop which is why he is asking that I think – DotNetRussell Jun 05 '14 at 14:59
  • 1
    You don't "iterate" the UI in WPF because [**UI is NOT data**](http://stackoverflow.com/a/14382137/643085). Create a proper ViewModel and use proper DataBinding and all your problems will magically disappear. – Federico Berasategui Jun 05 '14 at 15:00
  • @Jan Solo please select an answer if one worked for you – DotNetRussell Jun 06 '14 at 14:53

4 Answers4

1

See the solution here, it is essentially using a foreach in the follolwing fashion:

foreach (var item in listBox1.SelectedItems)
{
    // Do what you want here... Console.WriteLine(item), etc.
}

If you really want to do it with a for loop rather than a foreach, then do the following:

for(int i = selectedItems.Count - 1; i >= 0; --i)
{
    var item = selectedItems[i];
    // Do what you want with item
}
Community
  • 1
  • 1
GEEF
  • 1,175
  • 5
  • 17
  • Thx, it worked. Note: Using the for-loop, you can do it like this: DataRowView item = (DataRowView)this.listbox1.SelectedItems[i]; System.Windows.MessageBox.Show(Convert.ToString(item["FieldName"])); – Jan Solo Jun 06 '14 at 07:02
1

Here is your XAML bound to a Observable collection

  <ListBox ItemsSource="{Binding items}"/>

Here is your observable collection of objects

private ObservableCollection<Object> _items;

public ObservableCollection<Object> items{
  get{ return _items; }
}

Here is the enumeration over them and the removing of each item

for(int x = 0; x < _items.Count; x++){
   _items.Remove(_items.Where(n => n == _items[x]).Single());
   //You may have to do a notify property changed on this if the UI Doesnt update but thats easily googled.
   //Traditionally it would update. However since you are bound to items Im not sure if it will update when you manipulate _items
}
DotNetRussell
  • 9,716
  • 10
  • 56
  • 111
0

Create a second list. You still have to iterate twice, but the second iteration is not over the entire list of items.

var items List<ListBoxItem>;
foreach (var item in listbox1.SelectedItems)
    items.Add(item);

foreach (var item in items)
    listbox1.Remove(item);
Brian Watt
  • 225
  • 1
  • 7
0

Alternatively instead of enumerating twice you can create a copy of the list of objects and then remove the items from the original list while still enumerating.

        foreach (var selectedItem in listBox1.SelectedItems.Cast<List>())
        {
            //remove items from the original list here
        }
IdahoSixString
  • 643
  • 10
  • 18