DataGridView Custom Column Headings

During a project, I found that I needed to add full text titles to the column headings in an object bound DataGridView.

I had a couple of options, but in the end settled on the one outlined here.
Email Image

We all know that it is very easy to display a collection of objects in a DataGridView, the main problem is that the column heading text is the name of the property on the corresponding object. For example, if we have a class Person with a property called Fname then the column heading will be called Fname. So how can we have the column text set to something other than the property name or an expanded text such as "Forename" or "First Name"?

Obviously we could just manually set

dataGridView.Columns["ColumnName"].HeaderText = "First Name";

However we would end up writing lots of repetitive code.

The best way I've found is to create an attribute that lists the property name and the column title.

[AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
public class DataGridColumnBindingAttribute : Attribute
{
    private string title;
    private string property;

    public DataGridColumnBindingAttribute(string title, string property)
    {
        this.title = title;
        this.property = property;
    }

    public string Title
    {
        get
        {
            return this.title;
        }
    }

    public string Property
    {
        get
        {
            return this.property;
        }
    }
}

This attribute is then applied to an enum which describes the order that the columns are added to the DataGridView.

public enum PersonColumnHeadings
{
    [DataGridColumnBindingAttribute("Title", "Title")]
    Title = 1,
    [DataGridColumnBindingAttribute("Forename", "Forename")]
    Forename = 2,
    [DataGridColumnBindingAttribute("Surname", "Surname")]
    Surname = 3,
    [DataGridColumnBindingAttribute("Date of Birth", "DOB")]
    DOB = 4
}

We then have a method that returns all the details we need to build our column headings.

public static class DataGridViewBinding
{
    public static Dictionary<string, string> GetColumnBindings(Type enumType)
    {
        Dictionary<string, string> columnTitleDescriptions = new Dictionary<string, string>();

        // Look for our string value associated with fields in this enum.
        foreach (FieldInfo fi in enumType.GetFields())
        {
            // Check for our custom attribute.
            DataGridColumnBindingAttribute[] attrs =
                fi.GetCustomAttributes(typeof(DataGridColumnBindingAttribute), false)
                as DataGridColumnBindingAttribute[];

            if (attrs.Length > 0)
            {
                columnTitleDescriptions.Add(attrs[0].Title, attrs[0].Property);
            }
        }

        return columnTitleDescriptions;
    }
}

This returns a dictionary of titles and the corresponding property.

We then need a method to build the columns given an enum with DataGridColumnBinding attributes on it.

private void CreateDataGridViewColumns(DataGridView dataGridView, Type enumType)
{
    dataGridView.AutoGenerateColumns = false;
    Dictionary<string, string> columnBindings = DataGridViewBinding.GetColumnBindings(enumType);

    foreach (KeyValuePair<string, string> binding in columnBindings)
    {
        // Add the column to the DataGridView, adding the name of the column, the header text (title)
        // and the property to bind to.

        DataGridViewColumn column = dataGridView.Columns[
            dataGridView.Columns.Add(binding.Key, binding.Key)];
        column.DataPropertyName = binding.Value;
    }
}

This could be added as a static method on your own "extended" DataGridView, as an extension method or simply a utility method.

To call it, we call the method, passing it the DataGridView that we want to add the column headings to and the enum that describes the headings.

this.CreateDataGridViewColums(this.dataGridView1, typeof(PersonColumnHeadings));

The requirements for this to work are:

  1. The property in the DataGridColumnBinding must exactly match the name of the property on the class that is bound to the data grid otherwise the column will be empty.
  2. The values in the enum must be in the order that you want the columns shown (enum value 1 will be the furthest left column).

These classes are also part of the TR3V assembly in the TR3V.Windows.Forms namespace.

This article was published on the 3rd August 2008 and last updated 4th April 2009
Licence information / Terms of use

All code supplied on this site be it within the assembly or code samples is supplied as is. I take no responsibility for any of the code provided. As always with code samples & frameworks, use it at your own risk.

All applications and tutorials where C# code is provided in either text or a class file may be freely used and modified if you so desire.

The assembly is compiled against .net 3.5. There will not be a 2.0 compatible version so if you wish to use the assebly you will need to be using Visual Studio 2008 with the .net 3.5 framework installed.

The assembly may be used within in commercial and personal software free of charge but may not be resold on its own. To clarify, you may build an application on top of any of the functionality provided by the assembly (e.g using the code contract framework inside your application).

Support, suggestions and bugs can be submitted via my contact form however it is offered on a limited basis with no guaranteed response or response time.

Any updates or bug fixes will be included in any further downloads once releases on the site but note that there is no "update" service available so you would need to manually update any code.