2017-11-30 6 views
1

그래서 DataGridview를 채울 클래스에 데이터를 동적으로 추가해야합니다. 아래는 테스트 코드입니다. DataGridview를 사용하여 양식을 만들고 데이터 세트의 각 속성에 해당하는 datapropertynames를 사용하여 원하는 순서대로 열을 수동으로 추가했습니다. 그러나 datagridview는 그것들을 재정렬하고 나는 이유를 이해할 수 없다. data2, data1, CustomerName의 순서를 가지도록 datagridview를 설정했지만 customername은 data2와 data1 사이를 계속 이동합니다. 나는 이것이 무엇을하려고하는지와 함께 이상하게 보일지 모른다. 그러나 이것은 단지 개념의 시험이었다. 구현은 다른 열의 데이터를 기반으로 계산 된 열이 있지만 해당 열은 데이터에 바인딩되지 않기 때문에 정렬 할 수 없다는 것입니다. 따라서 계산 된 열의 데이터를 바인드하여 정렬 할 수 있도록이 작업이 필요합니다. 감사합니다C# 동적으로 DataGridview 순서로 속성을 추가했습니다.

public partial class Form1 : Form 
{ 
    public Form1() 
    { 
     InitializeComponent(); 
    } 
    public static Type BuildDynamicTypeWithProperties() 
    { 
     AppDomain myDomain = Thread.GetDomain(); 
     AssemblyName myAsmName = new AssemblyName(); 
     myAsmName.Name = "MyDynamicAssembly"; 

     // To generate a persistable assembly, specify AssemblyBuilderAccess.RunAndSave. 
     AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(myAsmName, 
                 AssemblyBuilderAccess.RunAndSave); 
     // Generate a persistable single-module assembly. 
     ModuleBuilder myModBuilder = 
      myAsmBuilder.DefineDynamicModule(myAsmName.Name, myAsmName.Name + ".dll"); 



     TypeBuilder myTypeBuilder = myModBuilder.DefineType("CustomerData", 
                 TypeAttributes.Public); 
     myTypeBuilder.SetParent(typeof(TestData)); 

     FieldBuilder customerNameBldr = myTypeBuilder.DefineField("customerName", 
                 typeof(string), 
                 FieldAttributes.Private); 

     // The last argument of DefineProperty is null, because the 
     // property has no parameters. (If you don't specify null, you must 
     // specify an array of Type objects. For a parameterless property, 
     // use an array with no elements: new Type[] {}) 
     PropertyBuilder custNamePropBldr = myTypeBuilder.DefineProperty("CustomerName", 
                 System.Reflection.PropertyAttributes.HasDefault, 
                 typeof(string), 
                 null); 

     // The property set and property get methods require a special 
     // set of attributes. 
     MethodAttributes getSetAttr = 
      MethodAttributes.Public | MethodAttributes.SpecialName | 
       MethodAttributes.HideBySig; 

     // Define the "get" accessor method for CustomerName. 
     MethodBuilder custNameGetPropMthdBldr = 
      myTypeBuilder.DefineMethod("get_CustomerName", 
             getSetAttr, 
             typeof(string), 
             Type.EmptyTypes); 

     ILGenerator custNameGetIL = custNameGetPropMthdBldr.GetILGenerator(); 

     custNameGetIL.Emit(OpCodes.Ldarg_0); 
     custNameGetIL.Emit(OpCodes.Ldfld, customerNameBldr); 
     custNameGetIL.Emit(OpCodes.Ret); 

     // Define the "set" accessor method for CustomerName. 
     MethodBuilder custNameSetPropMthdBldr = 
      myTypeBuilder.DefineMethod("set_CustomerName", 
             getSetAttr, 
             null, 
             new Type[] { typeof(string) }); 

     ILGenerator custNameSetIL = custNameSetPropMthdBldr.GetILGenerator(); 

     custNameSetIL.Emit(OpCodes.Ldarg_0); 
     custNameSetIL.Emit(OpCodes.Ldarg_1); 
     custNameSetIL.Emit(OpCodes.Stfld, customerNameBldr); 
     custNameSetIL.Emit(OpCodes.Ret); 

     // Last, we must map the two methods created above to our PropertyBuilder to 
     // their corresponding behaviors, "get" and "set" respectively. 
     custNamePropBldr.SetGetMethod(custNameGetPropMthdBldr); 
     custNamePropBldr.SetSetMethod(custNameSetPropMthdBldr); 


     Type retval = myTypeBuilder.CreateType(); 

     // Save the assembly so it can be examined with Ildasm.exe, 
     // or referenced by a test program. 
     myAsmBuilder.Save(myAsmName.Name + ".dll"); 
     return retval; 
    } 
    private void Form1_Load(object sender, EventArgs e) 
    { 
     Type custDataType = BuildDynamicTypeWithProperties(); 

     PropertyInfo[] custDataPropInfo = custDataType.GetProperties(); 
     foreach (PropertyInfo pInfo in custDataPropInfo) 
     { 
      Console.WriteLine("Property '{0}' created!", pInfo.ToString()); 
     } 

     Console.WriteLine("---"); 
     // Note that when invoking a property, you need to use the proper BindingFlags - 
     // BindingFlags.SetProperty when you invoke the "set" behavior, and 
     // BindingFlags.GetProperty when you invoke the "get" behavior. Also note that 
     // we invoke them based on the name we gave the property, as expected, and not 
     // the name of the methods we bound to the specific property behaviors. 

     object custData = Activator.CreateInstance(custDataType); 

     ((TestData)custData).data1 = "This Works"; 
     ((TestData)custData).data2 = "This Works 2"; 
     custDataType.InvokeMember("CustomerName", BindingFlags.SetProperty, 
             null, custData, new object[] { "Joe User" }); 
     var list = new List<object>(); 

     /* var1.data1 = "Hello"; 
     var1.data2 = "World"; 
     list.Add(var1);*/ 
     list.Add(custData); 
     dataGridView1.DataSource = list; 

    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     var test = dataGridView1.Rows[0].DataBoundItem; 
    } 
} 

public class TestData 
{ 
    public string data1 { get; set; } 
    public string data2 { get; set; } 
} 
+0

'동적'을 사용할 수 없습니까? https://stackoverflow.com/questions/5573856/binding-a-gridview-to-a-dynamic-or-expandoobject-object/6298704#6298704 –

+0

을 참조하십시오. 그러나 일부 인스턴스에서는 데이터가 개체에 크게 의존하며 메서드를 사용하여 기본 코드 변경 (몇 천 줄)없이 데이터 테이블로 변환 할 방법이 없으므로 기본 클래스를 파생시키고 프로그래밍 방식으로 속성을 추가해야합니다. – lesyriad

답변

0

자동 고갈 칼럼을 사용 중지하여 해결했습니다. datagridview에서 만든 열을 지우고 데이터 소스에서 새 열을 생성하는 것 같습니다.