views:

1429

answers:

2

I display the contents of a table in the database using a ListBox. Each listbox item is populated with the Text property set to a friendly name, and the Value property set to the unique ID column. The database structure might look similar to the following:

CREATE TABLE GENERIC { FRIENDLY_NAME TEXT, ID INT }

I tried for almost an hour to convert the items of the listbox to an int[] using LINQ and ultimately failed. It is also important to distinguish between the selected and not selected items. Here is what i ended up writing:

System.Collections.Generic.LinkedList<int> 
            selected = new LinkedList<int>(), 
            notSelected = new LinkedList<int>();

        foreach (ListItem item in PhotoGalleryEdit_PhotoShoots.Items)
        {
            if (item.Selected)
                selected.AddFirst(Convert.ToInt32(item.Value));
            else
                notSelected.AddFirst(Convert.ToInt32(item.Value));
        }

 int []arraySelected = selected.ToArray();
 int []arrayNotSelected = notSelected.ToArray();

Can anyone show how this is done in LINQ?

(I write all my code in C# but any answers written in VB would be more than welcome)

A: 
int[] selected = (from item in PhotoGalleryEdit_PhotoShoots.SelectedItems.OfType<MyItem>() select item.Value).ToArray();

Edit: Added OfType call to get selected items to IEnumerable.

Edit II: For the not selected items:

int[] notSelected = (from item in PhotoGalleryEdit_PhotoShoots.Items.OfType<MyItem>() where !Array.Exists(selected, x => x == item.Value) select item.Value).ToArray();
sipwiz
SelectedItems would require a Cast<T>() or similar (it isn't IEnumerable<T>) - and you've dropped the Convert.ToInt32
Marc Gravell
I tested with an IList<MyItem> instead of an IList which you have correctly pointed out is what SelectedItems returns. Luckily there is a nice OfType method for the SelectedItems which returns an IEnumerable object making it a nice one line solution.
sipwiz
+4  A: 

From your description, the least messy I can come up with is:

var qry = from ListItem item in listbox.Items
          select new {item.Selected, Value = Convert.ToInt32(item.Value)};

int[] arrSelected=qry.Where(x=>x.Selected).Select(x=>x.Value).ToArray();
int[] arrNotSelected=qry.Where(x=>!x.Selected).Select(x => x.Value).ToArray();

Since you are using AddFirst, you might also need a .Reverse() in there somewhere - or use Array.Reverse() afterwards.

Marc Gravell
This works for me and is very clean.
SmokingRope