Используя отражение, вы можете создать коллекцию объектов dynamic
, а затем привязать к ней DataGrid
.
Существует большой ответ здесь о создании динамических классов:
How to dynamically create a class in C#?
Используя это, вы можете создать список свойств (которые будут столбцы в DataGrid) во время выполнения, как это
List<TypeBuilderNamespace.Field> myFields = new List<TypeBuilderNamespace.Field>();
myFields.Add(new TypeBuilderNamespace.Field("FirstName", Type.GetType("System.String")));
myFields.Add(new TypeBuilderNamespace.Field("Surname", Type.GetType("System.String")));
myFields.Add(new TypeBuilderNamespace.Field("Age", Type.GetType("System.Int32")));
Затем динамически создать свой класс
Type myDynamicType = TypeBuilderNamespace.MyTypeBuilder.CompileResultType(myFields);
Создание некоторых образцов данных
List<dynamic> people = new List<dynamic>();
dynamic person1 = Activator.CreateInstance(myDynamicType);
person1.FirstName = "John";
person1.Surname = "Smith";
person1.Age = 45;
people.Add(person1);
dynamic person2 = Activator.CreateInstance(myDynamicType);
person2.FirstName = "Emma";
person2.Surname = "Jones";
person2.Age = 18;
people.Add(person2);
Затем связать свои данные в сетке
DataGrid grid = new DataGrid();
grid.AutoGenerateColumns = true;
grid.ItemsSource = people;
Это дает следующие DataGrid

Я изменил код в ответ процитированном выше немного , так вот мой список этого для полноты:
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Reflection.Emit;
namespace TypeBuilderNamespace {
public class Field {
public String FieldName { get; set; }
public Type FieldType { get; set; }
public Field(String name, Type type) {
FieldName = name;
FieldType = type;
}
}
public static class MyTypeBuilder {
public static Type CompileResultType(List<Field> fields) {
TypeBuilder tb = GetTypeBuilder();
ConstructorBuilder constructor = tb.DefineDefaultConstructor(MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName);
FieldName(string) and FieldType(Type)
foreach (var field in fields)
CreateProperty(tb, field.FieldName, field.FieldType);
Type objectType = tb.CreateType();
return objectType;
}
private static TypeBuilder GetTypeBuilder() {
var typeSignature = "MyDynamicType";
var an = new AssemblyName(typeSignature);
AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run);
ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("MainModule");
TypeBuilder tb = moduleBuilder.DefineType(typeSignature
, TypeAttributes.Public |
TypeAttributes.Class |
TypeAttributes.AutoClass |
TypeAttributes.AnsiClass |
TypeAttributes.BeforeFieldInit |
TypeAttributes.AutoLayout
, null);
return tb;
}
private static void CreateProperty(TypeBuilder tb, string propertyName, Type propertyType) {
FieldBuilder fieldBuilder = tb.DefineField("_" + propertyName, propertyType, FieldAttributes.Private);
PropertyBuilder propertyBuilder = tb.DefineProperty(propertyName, PropertyAttributes.HasDefault, propertyType, null);
MethodBuilder getPropMthdBldr = tb.DefineMethod("get_" + propertyName, MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig, propertyType, Type.EmptyTypes);
ILGenerator getIl = getPropMthdBldr.GetILGenerator();
getIl.Emit(OpCodes.Ldarg_0);
getIl.Emit(OpCodes.Ldfld, fieldBuilder);
getIl.Emit(OpCodes.Ret);
MethodBuilder setPropMthdBldr =
tb.DefineMethod("set_" + propertyName,
MethodAttributes.Public |
MethodAttributes.SpecialName |
MethodAttributes.HideBySig,
null, new[] { propertyType });
ILGenerator setIl = setPropMthdBldr.GetILGenerator();
Label modifyProperty = setIl.DefineLabel();
Label exitSet = setIl.DefineLabel();
setIl.MarkLabel(modifyProperty);
setIl.Emit(OpCodes.Ldarg_0);
setIl.Emit(OpCodes.Ldarg_1);
setIl.Emit(OpCodes.Stfld, fieldBuilder);
setIl.Emit(OpCodes.Nop);
setIl.MarkLabel(exitSet);
setIl.Emit(OpCodes.Ret);
propertyBuilder.SetGetMethod(getPropMthdBldr);
propertyBuilder.SetSetMethod(setPropMthdBldr);
}
}
}
удалить все это и использовать надлежащий XAML. –