Bindable LINQ: Comicster SubsetCollection
Update: SyncLINQ has been released under the name Bindable LINQ, and is available from CodePlex
Matt Hamilton posted an example of his SubsetCollection, a class which he uses in order to aggregate items. Towards the end, he suggests that SyncLINQ might have helped him. Allow me to answer that
Matt’s scenario is that he has two classes:
FolderTrade
Like a file system, a Folder is a special type of item that can contain other Folder items as well as Trade items. The Folder class contains a Folders property, a Trades property, and an Items property which contains both Folders and Trades.
His problem is simple - how can he keep Folders and Trades as separate collections, but also bring them both back in the Items property? Well, that’s easy - he could just loop through and create a new collection, right?
For a web applications, maybe. But for a WPF or Windows Forms application, that’s not enough; if he data binds to the Items collection, it needs to be updated whenever either Folders or Trades changes. How does he keep them in sync? Why, he needs SyncLINQ!
Here is how we might rewrite his Folder class to take advantage of SyncLINQ:
public class Folder : Item
{
private IBindableCollection<Item> _items;
private ObservableCollection<Folder> _folders;
private ObservableCollection<Trade> _trades;
public Folder()
{
_folders = new ObservableCollection<Folder>();
_trades = new ObservableCollection<Trade>();
_items = _folders.AsBindable<Folder, Item>()
.Union(
_trades.AsBindable<Trade, Item>());
}
public IList<Folder> Folders
{
get { return _folders; }
}
public IList<Trade> Trades
{
get { return _trades; }
}
public IBindableCollection<Item> Items
{
get { return _items; }
}
}
There is no need for his SubsetCollection class anymore, because the Union operator will bring both collections back together.
Now suppose Matt wanted to ensure the items were always sorted when displayed. Folders should appear first, then Trades. All he would have to do is change the query to:
_items = _folders.AsBindable<Folder, Item>()
.OrderBy(f => f.Name)
.Union(
_trades.AsBindable<Trade, Item>()
.OrderBy(t => t.Name));
I’ll admit, I did have to make a slight change to the AsBindable() extension to allow it to convert the collection down to a base class. That’s a pretty generic thing to do, though, and hopefully it will be useful to other people too.
Thanks for the scenario Matt!
Filed under: Bindable LINQ

Hi Paul,
Yes, it looks fantastic.
Can it handler inserts on the Items collection?
Marc
Hi Marc,
Good question, but unfortunately the answer is no. Just like with regular LINQ, the results of the query are read-only.
For a simple Where or Union it would be possible, but if you do a projection, it’s hard to enable inserts - because you’d have to “reverse project” to the source of the query, which would be somewhat impossible.
Cheers,
Paul