Here's a simple LINQ query in C# 3.0:
var people = new ObservableCollection<Person>(); var friends = new ObservableCollection<string>(); var myFriendsAges = from p in people join f in friends on p.Name equals f select p.Age;
Using ObservableCollection<T> from .NET 3.0 doesn't buy us anything that List<T> wouldn't. We end up creating an ordinary sequence, IEnumerable<int>. But, it doesn't have to be this way, LINQ is easily extended. Read on.
For use in RikReader's hierarchical view I implemented a new collection class, StackedList<T>. This is similar to System.Windows.Data.CompositeCollection in that I can flatten multiple collections into a single list. But StackedList is far more generic, it will directly flatten any IList<T>, and should the child list implement INotifyCollectionChanged, the collection change events are remapped such that StackedList is able to provide a complete read-only illusion of a virtual collection.
StackedList<int> list = new StackedList<int>(); Console.WriteLine(list.Count); // -> "0" ObservableCollection<int> childList = new ObservableCollection<int>(); childList.Add(1); list.AddCollection(childList); Console.WriteLine(list.Count); // -> "1" childList.Add(2); Console.WriteLine(list.Count); // -> "2" Console.WriteLine("{0}, {1}", list[0], list[1]); // -> "1, 2"
If we tried to write the same program using CompositeCollection we'd probably end up with something like this:
CompositeCollection composite = new CompositeCollection(); CollectionView view = CollectionViewSource.GetDefaultView(composite) as CollectionView; Console.WriteLine(view.Count); // -> "0" ObservableCollection<int> childList = new ObservableCollection<int>(); childList.Add(1); CollectionContainer container = new CollectionContainer(); container.Collection = childList; composite.Add(container); Console.WriteLine(view.Count); // -> "1"
Even though CollectionView has a Count property, it doesn't implement IList, it actually exposes a new list like interface ICollectionView which is IEnumerable. CollectionView is also non-generic, but notwithstanding, it is a similar approach.
With StackedList I was easily able to flatten a hierarchy of Feeds and Folders into a single, observable list of Items - which was then directly bindable for visualisation.
Stay tuned for Part 2, where we will explore the application of some other virtual lists.
