OdeToCode IC Logo

What’s Wrong With This Code #24

Wednesday, February 10, 2010

Sometimes the simplest solution introduces a bug.

Let’s say there is a ListBox in WPF (or Silverlight) displaying bowlers* and their bowling scores:

 <ListBox ItemsSource="{Binding Bowlers}" >
     <ListBox.ItemTemplate>
         <DataTemplate>
             <StackPanel Orientation="Horizontal">
                 <TextBlock Text="{Binding Name}"/>
                 <TextBlock Text="{Binding Score}"/>
             </StackPanel>                             
         </DataTemplate>
     </ListBox.ItemTemplate>
 </ListBox>

Behind the scenes, a view model includes a Bowlers property for the binding to work.

public IEnumerable<Bowler> Bowlers 
{ 
    get
    {
        return _bowlers;
    }
    set
    {
        if (value != _bowlers)
        {
            _bowlers = value.ToObservable();
            // ... Raise property changed event
        }
    }
}

The property uses a ToObservable extension method that works in either Silverlight or WPF.

public static class ObservableExtensions
{
    public static ObservableCollection<T> ToObservable<T>(this IEnumerable<T> items)
    {
        var collection = new ObservableCollection<T>();
        foreach(var item in items)
        {
            collection.Add(item);
        }
        return collection;
    }
}

So far everything is working. Bowlers appear on the screen, and as new bowlers get added to the collection …

_bowlers.Add(newBowler);

… they magically appear in the display.

The Change

Now someone wants the bowlers list sorted with the highest score appearing at the top of the list. Sounds like a simple change to the Bowlers property:

public IEnumerable<Bowler> Bowlers 
{ 
    get
    {
        return _bowlers.OrderByDescending(bowler => bowler.Score);
    }
    set
    {
        // same as before ...
    }
}

At first glace, the new code works and the bowlers appear in sorted order, but something is wrong! What will break?

Hint:

Bowlers added with _bowlers.Add(…) never appear in the display. Why is that?

 

* Of the ten pin variety - not the spinning kind.