How to display enum values in datagridview column

I wouldn't do it on CellFormatting. I would attack the DataTable itself. I would add a row that has the type of the enum, and the loop through the table and add the values. Something like this:

    private void Transform(DataTable table)
    {
        table.Columns.Add("EnumValue", typeof(SomeEnum));
        foreach (DataRow row in table.Rows)
        {
            int value = (int)row[1]; //int representation of enum
            row[2] = (SomeEnum)value;
        }
    }

Then, in your DataGridView just hide the column that has the integer representation of your enum.


You can use the CellTemplate property of the respective column. So first create a class for the cell template, overriding GetFormattedValue

public class VATGridViewTextBoxCell : DataGridViewTextBoxCell
{
    protected override object GetFormattedValue(object value, int rowIndex, ref DataGridViewCellStyle cellStyle, TypeConverter valueTypeConverter, TypeConverter formattedValueTypeConverter, DataGridViewDataErrorContexts context)
    {
        Price.VATRateEnum r = (Price.VATRateEnum)(int)value;
        switch (r)
        {
            case Price.VATRateEnum.None: return "0%";
            case Price.VATRateEnum.Low: return "14%";
            case Price.VATRateEnum.Standard: return "20%";
            default:
                throw new NotImplementedException()
        }
    }
}

then assign new instances of it to the columns' cell templates. Note that the change does not take effect until you refresh the grid and that's why I put it into the constructor:

public frmGoods()
{
    InitializeComponent();
    this.sellingVATDataGridViewTextBoxColumn.CellTemplate = new VATGridViewTextBoxCell();
    this.buyingVATDataGridViewTextBoxColumn.CellTemplate = new VATGridViewTextBoxCell();
}

Since you say this DGV is "read-only", you could read the data table into a list of a custom type that performs the conversion in-place.

You can get rid of the try-catch and your custom method and simply write:

e.Value = ((StatusType)e.Value).ToString();

If the value doesn't parse, it will be displayed as its integer value. That will speed things up a bit.