Month: December 2008

Using ObservableCollection with Linq

It’s not easy. Let’s say you’ve got a composite object which contains an observable collection (because you want to bind it to a list box for example). Then let’s say you want to populate this from a Linq query (Linq to XML for example). You soon run into the rather large gap becaue, unlike List<T>, ObservableCollection doesn’t have a suitable way to initialise it with a collection (not one that’s suitable for use in a Linq query.

Here’s how I fixed it in my project first. Rather than simply using ObservableCollection<PictureData> directly, create a new class that overrides it and adds an additional constructor:

    public class PictureDataList : ObservableCollection<PictureData>
        public PictureDataList()

        public PictureDataList(IEnumerable<PictureData> items)
            foreach (var item in items)

This method can be safely used in any Linq query.

But there’s a slightly better way – one which avoids having to code up a specific class for each type of object we want. We can add an extension method to ObservableCollection to populate the list from an IEnumerable, like this:

public static class LinqHelper
    public static ObservableCollection<T> PopulateFrom<T>(this ObservableCollection<T> collection, IEnumerable<T> range)
        foreach (var x in range)
        return collection;

You can use this in any linq select queryby doing:

var query = from regel in document.Element("Regions").Elements("Region")
                             select new MapRegion(this)
                                 Category = regel.Element("Category").Value,
                                 Description = regel.Element("Description").Value,
                                 Title = regel.Element("Title").Value,
                                 Route = new Route(regel.Element("Route")) { map = mapControl },
                                 Pictures = new ObservableCollection<PictureData>().PopulateFrom( 

                                     from pixel in regel.Element("Pictures").Elements("Picture")
                                     select new PictureData()
                                         Picture = pixel.Element("Url").Value,
                                         Audio = pixel.Element("Audio").Value

Why does my WrapPanel scroll when it’s used as an ItemsPanel?

I’m customising a ListBox (in WPF, not Silverlight) and I want it to live in a WrapPanel rather than a vertically scrollingStackPanel. So my template looks like this:

        <ItemsPanelTemplate x:Key="DrivePanelTemplate">
                <WrapPanel IsItemsHost="True" Orientation="Vertical" />

Simple enough. And my ListBox definition looks like this:

<ListBox x:Name="Drives" 
                     ItemsPanel="{DynamicResource DrivePanelTemplate}" 
                     ItemTemplate="{DynamicResource DriveTemplate}">

Simple enough. The Height constraint makes sure the items will wrap if there’s enough of them. But when I run it, I get a scroll bar and a single column, not the two columns I want. This seemed odd, since I haven’t specified a scrollviewer.

What I’m missing is that ListBox does specify a scrollviewer and it’s kicking in for me. The fix is to add


to the ListBox declaration, and this stops the implicit scrollviewer kicking in, and the WrapPanel does its job as required. Easy.