Binding an enum in a datatable

2 posts, 0 answers
  1. Anthony Daniel
    Anthony Daniel avatar
    2 posts
    Member since:
    Jul 2008

    Posted 16 Feb 2012 Link to this post

    I have bound a BindingList holding my business objects to a GridView which displays fine.  Then I reset the grid and I converted the list to a DataTable and bind it to a gridview.  The business objects have an enum property for which the appropriate string name is displayed when the objects are bound, however only the integer value of the enum is displayed when the datatable is bound.  I use the same predefined group of GridViewDataColumns for both scenarios.  The extension method generates a datacolumn with the datatype of my enum.  What should I do to get the enum string name to display when the datatable is bound?  I just want the string in a textbox, this grid is strictly read only.

    List<WorkItem> _workitems = new List<WorkItem>();
    List<GridViewDataColumn> _workitemColumns = new List<GridViewDataColumn>();
     
    _workitemColumns.Add(new GridViewTextBoxColumn() { DataField = "InstanceID", HeaderText = "Instance ID" });
    _workitemColumns.Add(new GridViewTextBoxColumn() { DataField = "StorageObjectID", HeaderText = "Object ID" });
    _workitemColumns.Add(new GridViewTextBoxColumn() { DataField = "Document.BatchID", HeaderText = "Batch ID" });
    _workitemColumns.Add(new GridViewTextBoxColumn() { DataField = "ReferenceTypeName", HeaderText = "Document Type" });
    _workitemColumns.Add(new GridViewDateTimeColumn() { DataField = "CreateDate", HeaderText = "Create Date", ExcelExportType = DisplayFormatType.Custom, ExcelExportFormatString = "MM/dd/yyyy hh:mm:ss" });
    _workitemColumns.Add(new GridViewTextBoxColumn() { DataField = "Title", HeaderText = "Title" });
    _workitemColumns.Add(new GridViewTextBoxColumn() { DataField = "OwningUser", HeaderText = "Assigned User" });
    _workitemColumns.Add(new GridViewTextBoxColumn() { DataField = "Status", HeaderText = "Status"});
     
    #region this works
     
    foreach (GridViewDataColumn curCol in this._workitemColumns)
    {
        this.workItemsGridView1.Columns.Add(curCol);
    }
     
    BindingList<WorkItem> bindingWorkitems = new BindingList<WorkItem>(this._workitems);
    BindingSource dbBindSource = new BindingSource();
    dbBindSource.DataSource = bindingWorkitems;
    this.workItemsGridView1.DataSource = dbBindSource;
     
    #endregion
     
    #region does not work
     
    DataTable workitemsDT = this._workitems.ToDataTable();
     
    foreach (GridViewDataColumn curCol in this._workitemColumns)
    {
        this.workItemsGridView1.Columns.Add(curCol);
    }
     
    foreach(GridViewDataColumn curCol in this._layerColumns[this._selectedLayer])
    {
        this.workItemsGridView1.Columns.Add(curCol);
    }
     
    this.workItemsGridView1.DataSource = workitemsDT;
     
    #endregion
     
    public static DataTable ToDataTable<T>(this List<T> items)
    {
        var tb = new DataTable(typeof(T).Name);
     
        PropertyInfo[] props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
     
        foreach (var prop in props)
        {
        if (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
        {
            tb.Columns.Add(prop.Name, prop.PropertyType.GetGenericArguments()[0]);
        }
        else
            tb.Columns.Add(prop.Name, prop.PropertyType);
        }
     
        foreach (var item in items)
        {
        var values = new object[props.Length];
        for (var i = 0; i < props.Length; i++)
        {
            values[i] = props[i].GetValue(item, null);
        }
     
        tb.Rows.Add(values);
        }
     
        return tb;
    }
  2. Julian Benkov
    Admin
    Julian Benkov avatar
    1135 posts

    Posted 21 Feb 2012 Link to this post

    Hello Anthony,

    You can check the PropertyInfo type for Enum and get the name of the variable in this case to save it in the DataTable. In addition, you should create a string DataColumn in this scenario:

    public static DataTable ToDataTable<T>(this List<T> items)
    {
        var tb = new DataTable(typeof(T).Name);
     
        PropertyInfo[] props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
     
        foreach (var prop in props)
        {
            if (prop.PropertyType.IsEnum)
            {
                tb.Columns.Add(prop.Name, typeof(string));
            }
            else if (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
            {
                tb.Columns.Add(prop.Name, prop.PropertyType.GetGenericArguments()[0]);
            }
            else
                tb.Columns.Add(prop.Name, prop.PropertyType);
        }
     
        foreach (var item in items)
        {
            var values = new object[props.Length];
            for (var i = 0; i < props.Length; i++)
            {
                if (props[i].PropertyType.IsEnum)
                {
                    object val = props[i].GetValue(item, null);
                    values[i] = Enum.GetName(props[i].PropertyType, val);
                }
                else
                {
                    values[i] = props[i].GetValue(item, null);
                }
            }
     
            tb.Rows.Add(values);
        }
     
        return tb;
    }public static DataTable ToDataTable<T>(this List<T> items)
    {
        var tb = new DataTable(typeof(T).Name);
     
        PropertyInfo[] props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance);
     
        foreach (var prop in props)
        {
            if (prop.PropertyType.IsEnum)
            {
                tb.Columns.Add(prop.Name, typeof(string));
            }
            else if (prop.PropertyType.IsGenericType && prop.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
            {
                tb.Columns.Add(prop.Name, prop.PropertyType.GetGenericArguments()[0]);
            }
            else
                tb.Columns.Add(prop.Name, prop.PropertyType);
        }
     
        foreach (var item in items)
        {
            var values = new object[props.Length];
            for (var i = 0; i < props.Length; i++)
            {
                if (props[i].PropertyType.IsEnum)
                {
                    object val = props[i].GetValue(item, null);
                    values[i] = Enum.GetName(props[i].PropertyType, val);
                }
                else
                {
                    values[i] = props[i].GetValue(item, null);
                }
            }
     
            tb.Rows.Add(values);
        }
     
        return tb;
    }

    I hope this helps.

    All the best,
    Julian Benkov
    the Telerik team
    Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
Back to Top