Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# listbox Collection syntax

While learning C# pretty fast, I am stumbling on this Collection syntax problem.

I added a number of objects of my own type MyItem to listbox lstData. Now I need to search in this listbox and thought of using the elegant LINQ notation like:

lstData.Items.Where(x => x.Text == SearchString)

but the Items of a listbox does not have a .Where(), although I did include the "using System.Linq;" namespace.

So I tried:

foreach (MyItem item in (MyItem)lstData.Items)

but this gives the build error: Cannot convert type 'System.Windows.Forms.ListBox.ObjectCollection' to 'MySandbox.frmListboxDemo.MyItem'.

I did manage to write something workable:

        for (int i = 0; i < lstData.Items.Count; i++)
        {
            MyItem item = (MyItem)lstData.Items[i];
            if (item.Text == SearchString)
            {
                lstData.SetSelected(i, true);
                break;
            }
        }

and a similar version like:

        var item_enum = lstData.Items.GetEnumerator();
        while (item_enum.MoveNext()) { etc etc... }

which turned out to be 2 lines longer, and without figuring what could replace 'var'.

I am not really sure I understand how to use Collections, ObjectCollections, Enumerators etc, but am eager to learn. Especially if a .Where() version is possible and/or better.


Thanks for all your answers. I ended up with this solution:

        var item_iter = lstData.Items.Cast<MyItem>()
                          .Where(x => x.Text.Trim().ToLower() == txtItemName.Text);
        foreach (MyItem item in item_iter)
        {
            int i = lstData.Items.IndexOf(item);
            lstData.SetSelected(i, true);
            break;
        }

I don't know if this is really much better than the "fortran" way (see above), but it does teach me methods I can use in other C# queries.

like image 584
Roland Avatar asked Nov 26 '12 15:11

Roland


1 Answers

The items collection is no strongly typed collection. You can use the IEnumerable<T>.OfType() or IEnumerable<T>.Cast() extension methods to get the entry to the LINQ world where you can filter your entries:

var filteredItems = lstData.Items.OfType<MyItem>().Where(i => i.Prop == val);

The difference between Cast and OfType is:

  • OfType<T> will just return the items which are castable to Type T
  • Cast<T> will fail, when at least one item is in the collection which is not castable to T
like image 87
Jan Avatar answered Sep 23 '22 05:09

Jan