Binding a GridView to a Dynamic or ExpandoObject object

后端 未结 6 471
离开以前
离开以前 2020-12-03 03:43

I\'m using Rob Conery\'s Massive ORM, and I haven\'t been able to bind the resulting ExpandoObject to a GridView.

I did find another Stacko

相关标签:
6条回答
  • I adapted Brian's accepted answer to be a little more concise and LINQ-y:

    public static DataTable ToDataTable(this IEnumerable<dynamic> items)
    {
        var list = items.Cast<IDictionary<string, object>>().ToList();
        if(!list.Any()) return null;
    
        var table = new DataTable();
        list.First().Keys.Each(x => table.Columns.Add(x));
        list.Each(x => x.Values.Each(y => table.Rows.Add(y)));
    
        return table;
    }
    

    (This assumes you've defined an IEnumerable.Each extension, which every codebase I've worked on has had).

    0 讨论(0)
  • 2020-12-03 04:01

    If we are talking GridView (meaning not WPF) then impromptu can proxy an expando to a poco given an interface. Say we have a list of expando's you can convert them to poco's:

    IEnumerable<IMyInterface> listOfPocos
           = Impropmtu.AllActLike<IMyInterface>(listOfExpandos, typeof(INotifyPropertyChanged));
    
    0 讨论(0)
  • 2020-12-03 04:03

    Since you can't bind to an ExpandoObject, you can convert the data into a DataTable. This extension method will do that for you. I might submit this for inclusion to Massive.

    /// <summary>
    /// Extension method to convert dynamic data to a DataTable. Useful for databinding.
    /// </summary>
    /// <param name="items"></param>
    /// <returns>A DataTable with the copied dynamic data.</returns>
    public static DataTable ToDataTable(this IEnumerable<dynamic> items) {
        var data = items.ToArray();
        if (data.Count() == 0) return null;
    
        var dt = new DataTable();
        foreach(var key in ((IDictionary<string, object>)data[0]).Keys) {
            dt.Columns.Add(key);
        }
        foreach (var d in data) {
            dt.Rows.Add(((IDictionary<string, object>)d).Values.ToArray());
        }
        return dt;
    }
    
    0 讨论(0)
  • 2020-12-03 04:07

    Ok, apparently as of now, you just can't bind a GridView control to an ExpandoObject instance. I had to use reflection to convert the ExpandoObject to a POCO class.

    0 讨论(0)
  • 2020-12-03 04:13

    adapting from Ben's answer

     public static DataTable ToDataTable(this IEnumerable<dynamic> items)
        {
            if (!items.Any()) return null;
    
            var table = new DataTable();
            bool isFirst = true;
    
            items.Cast<IDictionary<string, object>>().ToList().ForEach(x =>
            {
                if (isFirst) 
                  {
                    x.Keys.Select(y => table.Columns.Add(y)).ToList();
                    isFirst = false;
                  }
                table.Rows.Add(x.Values.ToArray());
            });
    
            return table;
        }
    
    0 讨论(0)
  • 2020-12-03 04:14

    I came to this thread after researching on the same topic, I found no solution but constructed my own as I desperately needed this one. So here is my solution without going POCO that really works.

    // Fill "list" with your dynamic objects.
    
    // cast a dynamic object to dictionary so we get the properties from it.
    var props = list[0] as IDictionary<string, object>;
    
    // create a datatable 
    var table = new System.Data.DataTable();
        foreach (var c in props.Keys)
            table.Columns.Add(new DataColumn(c));
    
    foreach (var o in list)
    {
        var row = table.NewRow();
        var op =  o as IDictionary<string, object>;
        foreach (var p in op.Keys)
        {
            row[p] = op[p];
        }
        table.Rows.Add(row);
    }
    

    And simply bind this table to your grid!

    I tested it and it worked for me.

    0 讨论(0)
提交回复
热议问题