Object Initializers And The WPF Data Grid

Today I began using the first version of the WPF data grid available on CodePlex.  So far everything is making sense but I got caught out by an unexpected behaviour with one of the new C# 3.0 features, object initializers.  The problem arose when I was trying to create columns in the data grid programmatically:

    dataGrid.Columns.Add(new DataGridTextColumn

    {

        Header = "First",

        Binding = new Binding("Length")

    });

Despite my insistence that the computer should accept this without complaint it threw up the following error:

A TwoWay or OneWayToSource binding cannot work on the read-only property 'Length' of type 'System.String[]'.

OK so it doesn't like binding to a read only property.  I found a few forum posts that indicated setting IsReadOnly on the column would cause it to become a one way binding which is what I really wanted:

    dataGrid.Columns.Add(new DataGridTextColumn

    {

        Header = "Length",

        Binding = new Binding("Length"),

        IsReadOnly = true

    });

This had no effect whatsoever.  A little confused, I went for a walk to puzzle over what I was doing and when I came back I made one simple change that solved the problem:

    dataGrid.Columns.Add(new DataGridTextColumn

    {

        Header = "Length",

        IsReadOnly = true,

        Binding = new Binding("Length")

    });

So there are two things I learnt today.

First, the properties you set in object initializers are set just like normal properties, in the order that you specify.  In general I would say that if you are making properties where the ordering is important, you might want to rethink your API if possible.  This little detail seems obvious now that I know it.

Second, WPF data binding is very eager and will try to apply any changes you make right away.  This is a big difference from ASP.Net data binding which is a very lazy and badly behaved beast.  If you want to mess with the setup of a WPF control in code, it might be easiest to do it before you bind any data to it.

17/11/2008 10:25 PM (UTC -08:00)