With a project that I am currently working on, I frequently need to display object information in a DataGridView. However, the values that needs to be displayed does not always directly belong to the bounded objects, instead, it is often a value related to the objects. Furthermore the DataGridView only accepts an IList of objects and it translates the properties of each object in the IList to the displayed values in the DataGridView. There are times when the IList readily available is not the list of objects we need to display information for, but rather another related or parent object.

In order to fill my needs, I ended up writing an extended version of the DataGridView, which is in some ways inspired by the amazing ObjectListView. The following code shows what is possible with ObjectGridView.

public class House
{
    public string GetAddress();
}

public class Person
{
    public string FirstName { get; set; }
    public string Street { set; }
    public Car Car { get; set; }
}

public class Car
{
   public string Model { get; set; }
}

public static main()
{
    var persons = new BindingList<Person>();
    var houses = new Dictionary<Person, House>();

    ObjectGridView ogv = new ObjectGridView();
    ObjectGridViewTextBoxColumn colName, colModel, colAddress;
    // ...

    // regular DataGridView data association
    colName.DataPropertyName = "FirstName";

    // display a sub object of the bounded object
    colModel.ValueGetter = delegate(object model)
    {
       Person p = (Person)model;
       return p.Car.Model;
    }

    // display related information via a method call
    colAddress.ValueGetter = delegate(object model)
    {
       return houses[(Person)model].GetAddress(); 
    }

    // customised value setting when cell is being edited
    colAddress.ValueSetter = delegate(object model, object value)
    {
        Person p = (Person)model;
        p.Street = Convert.ToString(value);
    }

    // regular DataGridView databinding for 2 way updating of UI and datasource
    ogv.DataSource = new BindingSource(persons, null);
}

Download JakeSee.Winforms.ObjectGridView