5

Consider the code:

ObservableCollection<string> cities = new ObservableCollection<string>();
ObservableCollection<string> states = new ObservableCollection<string>();

ListBox list;

cities.Add("Frederick");
cities.Add("Germantown");
cities.Add("Arlington");
cities.Add("Burbank");
cities.Add("Newton");
cities.Add("Watertown");
cities.Add("Pasadena");

states.Add("Maryland");
states.Add("Virginia");
states.Add("California");
states.Add("Nevada");
states.Add("Ohio");

CompositeCollection cmpc = new CompositeCollection();
CollectionContainer cc1 = new CollectionContainer();
CollectionContainer cc2 = new CollectionContainer();

cc1.Collection = cities;
cc2.Collection = states;

cmpc.Add(cc1);
cmpc.Add(cc2);

list.ItemsSource = cmpc;

foreach(var itm in cmpc)
{
    // itm is CollectionContainer and there are only two itm’s
    // I need the strings
}

While list shows the right data on the GUI

I need this data (without referring to the ListBox) and I am not getting it

abatishchev
  • 98,240
  • 88
  • 296
  • 433
Dudu
  • 61
  • 5

3 Answers3

4

Try this: foreach (var itm in cmpc.Cast<CollectionContainer>().SelectMany(x => x.Collection.Cast<string>()))

Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
  • this will iterate for the only first level CollectionContainer that won't get results – Amr Badawy Jun 09 '10 at 10:51
  • 2
    This is a nice trick.Isnt there a way to do it directly? How come the ListBox sees the strings? What does it use? – Dudu Jun 09 '10 at 11:06
2

The ListBox uses for its ItemsSource Property the default view of the collection, which you can use, too:

  foreach (string itm in CollectionViewSource.GetDefaultView(cmpc))
  {
    Debug.Print(itm);
  }

You can use the ICollectionView classes to sort or filter an ItemsSource, but be careful while this won't work properly with CompositeCollections, as you can see this question: How to handle a CompositeCollection with CollectionView features?

Community
  • 1
  • 1
Herm
  • 2,956
  • 19
  • 32
1

you should extract data from cmpc items and set them as data source as list.ItemsSource won't understand that u need to set inner items of items as a datasource
EDIT

You can use this method

List<string> GetData(CompositeCollection cmpc)
        {
            List<string> allStrings = new List<string>();
            foreach (var item in cmpc)
            {
                allStrings.AddRange(item.OfType<string>());
            }
            return allStrings;
        }

and set datasource

list.ItemsSource = GetData(cmpc);
Amr Badawy
  • 7,453
  • 12
  • 49
  • 84
  • his is a nice trick.Isnt there a way to do it directly? How come the ListBox sees the strings? What does it use? – Dudu Jun 09 '10 at 11:06
  • what did you mean by directly ? – Amr Badawy Jun 09 '10 at 11:50
  • something on the line of : foreach(var itm in cmpc) – Dudu Jun 14 '10 at 09:01
  • that's already what I did in the above code ,I just make your foreach loop extract strings and return it as a datasource for ListBox ... could you please clarify to me what you need exactly ? – Amr Badawy Jun 14 '10 at 12:02