Подтвердить что ты не робот

Связывание GridView с объектом Dynamic или ExpandoObject

Я использую Rob Conery Massive ORM, и я не смог связать полученный ExpandoObject с GridView.

Я нашел еще один вопрос Stackoverflow, который предлагает использовать фреймворк impromptu, но я не уверен, что это сработает для этого. Если вы знаете, что это так, укажите образец кода, чтобы фактически преобразовать ExpandoObject в то, к которому может привязать элемент управления GridView.

В худшем случае, кто-нибудь внедрил дополнительный метод (который можно использовать совместно) для Massive для преобразования полученного ExpandoObject в POCO?

любая помощь приветствуется. Спасибо.

4b9b3361

Ответ 1

Поскольку вы не можете привязываться к ExpandoObject, вы можете преобразовать данные в DataTable. Этот метод расширения сделает это за вас. Я могу представить это для включения в 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;
}

Ответ 2

Если мы говорим о GridView (а не WPF), то impromptu может проксировать расширение для poco с учетом интерфейса. Скажем, у нас есть список expando, вы можете конвертировать их в poco's:

IEnumerable<IMyInterface> listOfPocos
       = Impropmtu.AllActLike<IMyInterface>(listOfExpandos, typeof(INotifyPropertyChanged));

Ответ 3

Хорошо, по-видимому, с этого момента вы просто не можете привязать элемент GridView к экземпляру ExpandoObject. Мне пришлось использовать отражение для преобразования ExpandoObject в класс POCO.

Ответ 4

Я адаптировал Брайана к принятию ответа, чтобы быть немного более кратким и 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;
}

(Предполагается, что вы определили расширение IEnumerable.Each, которое у каждой кодовой базы, на которой я работал).

Ответ 5

Я пришел к этой теме после исследования по той же теме, я не нашел решения, но создал свой собственный, поскольку я отчаянно нуждался в этом. Итак, вот мое решение, не задумываясь о том, что POCO действительно работает.

// 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);
}

И просто привяжите эту таблицу к своей сетке!

Я тестировал его, и это сработало для меня.

Ответ 6

адаптация от ответа Бена

 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;
    }