Связывание GridView с объектом Dynamic или ExpandoObject
Я использую Rob Conery Massive ORM, и я не смог связать полученный ExpandoObject
с GridView
.
Я нашел еще один вопрос Stackoverflow, который предлагает использовать фреймворк impromptu, но я не уверен, что это сработает для этого. Если вы знаете, что это так, укажите образец кода, чтобы фактически преобразовать ExpandoObject
в то, к которому может привязать элемент управления GridView
.
В худшем случае, кто-нибудь внедрил дополнительный метод (который можно использовать совместно) для Massive для преобразования полученного ExpandoObject
в POCO?
любая помощь приветствуется. Спасибо.
Ответы
Ответ 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;
}