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)