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.