How to bind an object to a DataGridView

There are tons of articles out there on how to bind a list of object to a DataGridView. To save you the time, I’ll just say that if involves this:

myGridView.DataSource = myList; 

That’s quite lovely, but sometimes that’s not what we’re after.

Sometimes, I just want to bind a single object’s properties to a DataGridView for the purpose of just displaying the object and the values of it’s member variables. Ok Ok, so this is not exactly a “binding” since it’s not a two-way relationship, but first, binding something or someone in real life rarely is, and second, coming from a CS/EE background I am fairly used to relationships that are not necessarily two-way 🙂 .

So, say you have an object like this:



class CustomObject
{
    public string ObjectName { get; set; }
    public int ObjectNumber { get; set; }
    public DateTime ObjectTimestamp { get; set; }
    public List<string> WTF { get; set; }
    public CustomObject()
    {
        ObjectName = "Some Object Name";
        ObjectNumber = 1;                     // we are # 1
        ObjectTimestamp = DateTime.Now;
        WTF = new List<string>();
    }
}

And you want to display the member values in a DataGridView so that it looks like this:

Bound Grid

If this were a list of objects you just set the DataSource property of the DataGridView to your list, and there you have it. In this custom configuration, a little bit more chicanery is required… and it involves Relection… and here it is:



/// <summary>
/// "Binds" the public properties of an arbitrary object to a DataGridView
/// </summary>
/// <param name="dataObject">arbitrary object</param>
/// <param name="targetView">DataGridView that should display object properties</param>
private void BindObjectToGridView(object dataObject, DataGridView targetView)
{
    DataGridViewTextBoxCell cell = new DataGridViewTextBoxCell();
    if (targetView.Columns.Count < 2)
    {
        targetView.Columns.Add(new DataGridViewColumn() 
        { 
            CellTemplate = cell, 
            FillWeight = 1, 
            AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill, 
            ReadOnly = true 
        });
        targetView.Columns.Add(new DataGridViewColumn() 
        { 
            CellTemplate = cell, 
            FillWeight = 1, 
            AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill 
        });
    }
    targetView.Rows.Clear();
    Type dataObjectType = dataObject.GetType();
    foreach (PropertyInfo currentProperty in dataObjectType.GetProperties())
    {
        string propetyName = currentProperty.Name;
        object propertyValue = currentProperty.GetValue(dataObject, null);
        targetView.Rows.Add(new object[] { propetyName, propertyValue });
    }
}

That’s more or less it. As you can see, I am jsut going the ToString() route for object values. The side effect is that our List does not get properly displayed.. and I am not sure what a proper way to display it would be. I suppose you could check if the object implement IEnumerable,

if (currentProperty.PropertyType.GetInterfaces().Contains<Type>(typeof(IEnumerable)))
    foreach (object currentEnumerableItem in (IEnumerable)propertyValue)...

and then recursively get member values until you work your way down to basic types..but that’s outside the scope of my post.. so that’s it.

Happy coding,

Cheers!