You are missing a possible piece.
column.DataPropertyName = "Foo";
column.DisplayMember = "SomeNameField";
column.ValueMember = "Bar"; // must do this, empty string causes it to be
// of type string, basically the display value
// probably a bug in .NET
column.DataSource = from foo in Foo select foo;
grid.DataSource = data;
UPDATE:
Actually, after reading your question again, I think you are facing that noted bug. There is unfortunately no way to make it return the bound object without using a custom TypeDescriptor/TypeConverter/BindingSource.
Answer for binding to a complex object. No by default. I wrote quite a nice one for my current project. This involves making a custom TypeDescriptor/TypeConverter/BindingSource that returns all the nested properties. Another 'bug', you cant use '.' for a member separator, I had to resort to ':' instead.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…