DataGridviewにデータを追加するクラスにデータを動的に追加する必要があります。以下はテストコードです。私はdatagridviewでフォームを作成し、データセットの各プロパティに対応するdatapropertynamesを使用して、必要な順番で列を手動で追加しました。しかし、datagridviewはそれらを並べ替え、私は理由を理解できません。私はdata2、data1、CustomerNameの順序を持つようにdatagridviewを設定しますが、customernameはdata2とdata1の間を移動し続けます。私はこれが奇妙に見えるかもしれないことを知っていますが、これは単なる概念のテストに過ぎません。実装では、他の列のデータに基づいて計算される列がありますが、それらの列はデータにバインドされていないためソート可能ではありません。ですから、私はこれを動作させるために、またはソート可能なように計算された列のデータをバインドする方法が必要です。ありがとうC#動的にデータグリッドビューの順序でプロパティを追加する
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; }
}
「動的」を使用できませんか? https://stackoverflow.com/questions/5573856/binding-a-gridview-to-a-dynamic-or-expandoobject-object/6298704#6298704 –
を参照してください。ただし、データがオブジェクトに大きく依存する場合があります。そのオブジェクトのメソッドは、私はそれを私は基本的なコードの変更(数千行)せずにデータテーブルに変換する方法がないので、私は基本クラスを派生し、プロパティをプログラムで追加する必要があります。 – lesyriad