2015-06-03 7 views
0

Я создал несколько Datagrids динамически. В режиме динамического Datagrid создание номера и имени столбцов неизвестно заранее.WPF DataGrid: как добавить содержимое строки, которое определяется массивом Object?

Итак, я создал DataGrid, как показано ниже:

DataGrid grid = new DataGrid(); 
grid.Columns.Add(new DataGridTextColumn() { Header = randomHeader1 }); 
grid.Columns.Add(new DataGridTextColumn() { Header = randomHeader2 }); 
grid.Columns.Add(new DataGridTextColumn() { Header = randomHeader3 }); 
// The number of columns for each datagrid is variable 

Как я могу добавить строки в мой Datagrid? Например, я хотел бы добавить эти 3 строки в Dtatagrid, что я определил в верхней:

  1. а, б, в
  2. D, E, F
  3. г, H, I

Я пытался решить мою проблему, как показано ниже, но это не работает:

grid.Items.Add(new Object[] { "a", "b", "c" }); 
grid.Items.Add(new Object[] { "d", "e", "f" }); 
grid.Items.Add(new Object[] { "g", "h", "i" }); 

Пожалуйста, ознакомьтесь код и предоставить мне решение.

+0

удалить все это и использовать надлежащий XAML. –

ответ

0

Используя отражение, вы можете создать коллекцию объектов 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

enter image description here

Я изменил код в ответ процитированном выше немного , так вот мой список этого для полноты:

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