To get around this limitation we could define an intermediate class which we set the properties on, however we then need to write a class which is only used for one thing to support this. Fortunately we can use anonymous types in .net 3 to help.
Lets define a Person class and an Address class.
public class Person
{
public string Title { get; set; }
public string Forename { get; set; }
public string Surname { get; set; }
public DateTime DOB { get; set; }
public Address Address { get; set; }
public void DoStuff()
{
MessageBox.Show("Person.DoStuff called");
}
}
public class Address
{
public string Line1 { get; set; }
public string Line2 { get; set; }
public string Line3 { get; set; }
public string PostCode { get; set; }
}
Now we need to use a Linq query to select an anonymous type from the collection and shape the data as needed.
var peeps = from person in people
select new
{
Forename = person.Forename,
Surname = person.Surname,
DateOfBirth = person.DateOfBirth,
AddressLine1 = person.Address.Line1,
PostCode = person.Address.PostCode
};
We can then use this collection as a data source for our DataGridView.
this.dataGridView1.DataSource = new BindingSource { DataSource = peeps };
Now, lets say that once an identity has been verified, we want to click the person which would bring up their account details. Since we are using the anonymous type, we have no way to get back to the Person that we built the anonymous type from... actually, with a little bit of reflection we can!
The way to do it (with 3 additional lines of code) is to add a property with a specific name to the anonymous type which we know beforehand and will always use when doing this kind of activity. I suggest a name like DataEntityObject. To use it, we add 1 additional line to the declaration of the anonymous type.
var peeps = from person in people
select new
{
DataEntityObject = person,
Forename = person.Forename,
Surname = person.Surname,
DateOfBirth = person.DateOfBirth,
AddressLine1 = person.Address.Line1,
PostCode = person.Address.PostCode
};
Now to get hold of that DataEntityObject, we need the following helper method. This method will either return null if there is no property called DataEntityObject or it will return the object that is presented as the DataEntityObject property on our anonymous type.
private object GetDataEntityObjectFromAnonymousType(object anonymousObject)
{
Type anonymousObjectType = anonymousObject.GetType();
return (anonymousObjectType.GetProperty("DataEntityObject") == null)
? null
: anonymousObjectType.GetProperty("DataEntityObject").GetValue(anonymousObject, null);
}
We can then reference the selected person and call methods or set properties.
Person person =
(Person)GetDataEntityObjectFromAnonymousType(this.dataGridView1.SelectedRows[0].DataBoundItem);
person.DoStuff();
To stop the DataEntityObject from being shown in the DataGridView, you can leverage the code in my Custom DataGridView Column Headings tutorial.
This article was published on the 3rd August 2008
Last Edited 4th August 2008