如何将 <string, object> 字段的集合绑定到 GridControl WPF?

How to bind a Collection of <string, object> Fields to GridControl WPF?

我搜索google, community, 所以搜索和挖掘后才问这个问题

我有一个在 运行 时间填充的列和值的集合,因此我想从字段集合中填充 GridControl,但我不想使用 DataTable 或任何 ADO.NET 事物。只有 .net 集合。 我也不想使用固定 class 和固定属性,如 class Employee 并制作一个 Employee 列表。 不,我不需要,

我只需要在运行时从我的自定义字段列表或字典

创建 GridControl WPF 控件的列和值
List<Field> Fields {get;set;}

public class Field{
   public string ColumnID{get;set;}
   public object Value{get;set;}
}

测试阶段

Field field1 = new Field();
field1.ColumnID = "branchID";  // this column id at runtime i got it
field1.Value = 100;

Field field2 = new Field();
field2.ColumnID = "customerID"; // at runtime but this for example
field2.Value = 1; // at runtime but this for example

Field field3 = new Field();
field3.ColumnID = "Runtime-ColumnID" ;
field3.Value = RuntimeValue;

Fields.Add(field1);
Fields.Add(field2);
fields.Add(field3);

请问如何存档:

i Just want to fill GridControl from Collection of fields. Any suggestion like LINQ, dynamic binding will be appreaciated.

请看下面的代码;

注意:由于时间有限,我已经使用Newtonsoft json将最终对象(ExpendoObject)转换为匿名类型(因为expendo对象无法绑定到网格)。您可以改进代码。

此外,我在字段 class 中添加了附加 属性 "RowNumber",这将指示程序映射特定行中的列。

 public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        this.Loaded += MainWindow_Loaded;
    }

    private void MainWindow_Loaded(object sender, RoutedEventArgs e)
    {
        List<Field> fields = new List<Field> {
            new Field{ ColumnID="Name", Value="Kamran" , RowNumber=1},
            new Field{ ColumnID="Age", Value=25 , RowNumber = 1},
            new Field{ ColumnID="Name", Value="Asim", RowNumber = 2, },
            new Field{ ColumnID="Age", Value=30 , RowNumber = 2 },
            new Field{ ColumnID="Department", Value="Computer" , RowNumber = 2},
        };

        var result = fields.ToPivotArray(item => item.ColumnID, item => item.RowNumber, items => items.FirstOrDefault()?.Value);

        string json = JsonConvert.SerializeObject(result, new KeyValuePairConverter());
        var obj = JArray.Parse(json);
        testGrid.ItemsSource = obj;
    }
}

public static class Extension
{
    public static dynamic[] ToPivotArray<T, TColumn, TRow, TData>(this IEnumerable<T> source, Func<T, TColumn> columnSelector,
                                                                   Expression<Func<T, TRow>> rowSelector, Func<IEnumerable<T>, TData> dataSelector)
    {
        var arr = new List<object>();
        var cols = new List<string>();
        String rowName = ((MemberExpression)rowSelector.Body).Member.Name;
        var columns = source.Select(columnSelector).Distinct();
        //cols = (new[] { rowName }).Concat(columns.Select(x => x.ToString())).ToList();
        cols = (columns.Select(x => x.ToString())).ToList();
        var rows = source.GroupBy(rowSelector.Compile())
                         .Select(rowGroup => new
                         {
                             Key = rowGroup.Key,
                             Values = columns.GroupJoin(
                                 rowGroup,
                                 c => c,
                                 r => columnSelector(r),
                                 (c, columnGroup) => dataSelector(columnGroup))
                         }).ToArray();

        foreach (var row in rows)
        {
            var items = row.Values.Cast<object>().ToList();
            // items.Insert(0, row.Key);
            var obj = GetAnonymousObject(cols, items);
            arr.Add(obj);
        }
        return arr.ToArray();
    }
    private static dynamic GetAnonymousObject(IEnumerable<string> columns, IEnumerable<object> values)
    {
        IDictionary<string, object> eo = new ExpandoObject() as IDictionary<string, object>;
        int i;
        for (i = 0; i < columns.Count(); i++)
        {
            eo.Add(columns.ElementAt<string>(i), values.ElementAt<object>(i));
        }
        return eo;
    }

}

public class Field
{
    public string ColumnID { get; set; }
    public object Value { get; set; }
    public int RowNumber { get; set; }
}