Tuesday, November 16, 2010

.NET: IEnumerable is *not* lazy

Just spent ten minutes working this one out.

If you have a variable

IEnumerable<Foo> SomeFoos = [...LINQ expression returning an enumerable...];

and then do this

foreach (var foo in SomeFoos) { [...update foo...] }

you will almost certainly not see any changes in the values in SomeFoos.  Why not?  Because each time you iterate through SomeFoos, the enumerator is run again, quite possibly recreating each item.

A solution is to force each item in SomeFoos to be manifested once.  For example,

List<Foo> SomeFoos = [...LINQ expression returning an enumerable...].ToList();

Now things will work as expected.

[N.B.  When I say "laziness", I refer to the standard functional programming practice of replacing an evaluated thunk with the result, thereby avoiding any repeated processing effort on subsequent reads of the thunk.]

Thursday, November 11, 2010

WPF: Making ListBoxItems stretch the width of the ListBox

This is unbelievably hard for something which must be universally desired.

By default, ListBoxItems occupy the width required by their contents, not by the width of the containing ListBox.  This causes your optimistically formatted columns in each ListBox to fail to align.

Instead, add this in the Resources section:


<Style x:Key="StretchingListBoxItemStyle" TargetType="ListBoxItem">
  <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>


and add ItemContainerStyle="{StaticResource StretchingListBoxItemStyle}" to your ListBox attributes.

Strewth.