我如何在 C#(silverlight) 中创建一个动态类,我可以在其中循环属性
这是我的代码:
ObservableCollection<object> ll = new ObservableCollection<object>();
public MainPage(){
InitializeComponent();
ll= createobj(x2);
dataGrid2.ItemsSource = ll;
这是创建我的属性的函数。 我怎样才能将它们公开?
private PropertyInfo papa(string propertyName, TypeBuilder tb, Type tt){
private PropertyInfo papa(string propertyName, TypeBuilder tb, Type tt){
FieldBuilder ff = tb.DefineField("_" + propertyName, tt, FieldAttributes.Public);
PropertyBuilder pp =
tb.DefineProperty(propertyName,
PropertyAttributes.None ,
tt,
new Type[] {tt });
MethodBuilder mget =
tb.DefineMethod("get_value",
MethodAttributes.Public,
tt,
Type.EmptyTypes);
ILGenerator currGetIL = mget.GetILGenerator();
currGetIL.Emit(OpCodes.Ldarg_0);
currGetIL.Emit(OpCodes.Ldfld, ff);
currGetIL.Emit(OpCodes.Ret);
MethodBuilder mset =
tb.DefineMethod("set_value",
MethodAttributes.Public,
null,
new Type[] { tt });
ILGenerator currSetIL = mset.GetILGenerator();
currSetIL.Emit(OpCodes.Ldarg_0);
currSetIL.Emit(OpCodes.Ldarg_1);
currSetIL.Emit(OpCodes.Stfld, ff);
currSetIL.Emit(OpCodes.Ret);
pp.SetGetMethod(mget);
pp.SetSetMethod(mset);
return pp;
}
函数,
private ObservableCollection<object> createobj(XDocument xx){
AssemblyName assemblyName = new AssemblyName();
assemblyName.Name = "tmpAssembly";
AssemblyBuilder assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
ModuleBuilder module = assemblyBuilder.DefineDynamicModule("tmpModule");
TypeBuilder tb = module.DefineType("SilverlightApplication20.blabla", TypeAttributes.Public | TypeAttributes.Class);
int[] exista={0,0};
PropertyInfo pp;
foreach (XElement node in xx.Root.Descendants())
{
foreach (XAttribute xa in node.Attributes())
{
if (xa.Name.ToString() != "rind" && xa.Name.ToString() != "col")
pp = papa(xa.Name.ToString(), tb, typeof(string));
else
pp = papa(xa.Name.ToString(), tb, typeof(int));
}
}
pp=papa("nume",tb,typeof(string));
pp = papa("parinte", tb, typeof(string));
Type gg = tb.CreateType();
ObservableCollection<object> collection = new ObservableCollection<object>();
PropertyInfo[] pps = gg.GetProperties( );
foreach (XElement node in xx.Root.Descendants())
{
object obiect = Activator.CreateInstance(gg);
foreach (PropertyInfo property in pps)
{ if (property.Name == "nume" )
property.SetValue(obiect, node.Name.ToString(),null);
if (property.Name == "parinte")
property.SetValue(obiect, node.Parent.Name.ToString(), null);
}
foreach (XAttribute xa in node.Attributes())
{
string value="";
int value2=0;
{ if(xa.Name.ToString()!="rind" && xa.Name.ToString()!="col")
value = xa.Value;
else
value2 = int.Parse( xa.Value);
foreach (PropertyInfo property in pps)
{
if (property.Name == xa.Name.ToString())
{
if(xa.Name.ToString()=="rind" || xa.Name.ToString()=="col")
property.SetValue(obiect, value2, null);
else
property.SetValue(obiect, value, null);
break;
}
}
}
} collection.Add(obiect);
}
return collection;
}
这是创建我的对象 的
问题是我无法循环访问属性。
我想创建这样的东西:
public class blabla
{
public int property1{get;set;}
public int property2{get;set;}
}
并且能够做这样的事情,
object1.property=1;
这就是我所需要的: 我有一个如下所示的 xml 字符串:
<xml>
<col1 label="label1" r="1" c="1"/>
<col2 label="label2" r="2" c="1"/>
<col3 label="label2" r="2" c="2"/>
< /xml>
我想将它绑定到数据网格。 问题是我不知道运行时会有多少属性。
对于上面的例子,我可以创建一个这样的类:
public class blabla
{
public string labe{get;set;}
public int r{get;set;}
public int c{get;set;}
}
但正如我所说,可以有更多的属性。这就是为什么我需要动态的东西。 同时我需要能够迭代创建的属性
Here is my code:
ObservableCollection<object> ll = new ObservableCollection<object>();
public MainPage(){
InitializeComponent();
ll= createobj(x2);
dataGrid2.ItemsSource = ll;
this is the function that creates my properties.
how can I make them public?
private PropertyInfo papa(string propertyName, TypeBuilder tb, Type tt){
private PropertyInfo papa(string propertyName, TypeBuilder tb, Type tt){
FieldBuilder ff = tb.DefineField("_" + propertyName, tt, FieldAttributes.Public);
PropertyBuilder pp =
tb.DefineProperty(propertyName,
PropertyAttributes.None ,
tt,
new Type[] {tt });
MethodBuilder mget =
tb.DefineMethod("get_value",
MethodAttributes.Public,
tt,
Type.EmptyTypes);
ILGenerator currGetIL = mget.GetILGenerator();
currGetIL.Emit(OpCodes.Ldarg_0);
currGetIL.Emit(OpCodes.Ldfld, ff);
currGetIL.Emit(OpCodes.Ret);
MethodBuilder mset =
tb.DefineMethod("set_value",
MethodAttributes.Public,
null,
new Type[] { tt });
ILGenerator currSetIL = mset.GetILGenerator();
currSetIL.Emit(OpCodes.Ldarg_0);
currSetIL.Emit(OpCodes.Ldarg_1);
currSetIL.Emit(OpCodes.Stfld, ff);
currSetIL.Emit(OpCodes.Ret);
pp.SetGetMethod(mget);
pp.SetSetMethod(mset);
return pp;
}
this is the function that creates my object
private ObservableCollection<object> createobj(XDocument xx){
AssemblyName assemblyName = new AssemblyName();
assemblyName.Name = "tmpAssembly";
AssemblyBuilder assemblyBuilder = Thread.GetDomain().DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
ModuleBuilder module = assemblyBuilder.DefineDynamicModule("tmpModule");
TypeBuilder tb = module.DefineType("SilverlightApplication20.blabla", TypeAttributes.Public | TypeAttributes.Class);
int[] exista={0,0};
PropertyInfo pp;
foreach (XElement node in xx.Root.Descendants())
{
foreach (XAttribute xa in node.Attributes())
{
if (xa.Name.ToString() != "rind" && xa.Name.ToString() != "col")
pp = papa(xa.Name.ToString(), tb, typeof(string));
else
pp = papa(xa.Name.ToString(), tb, typeof(int));
}
}
pp=papa("nume",tb,typeof(string));
pp = papa("parinte", tb, typeof(string));
Type gg = tb.CreateType();
ObservableCollection<object> collection = new ObservableCollection<object>();
PropertyInfo[] pps = gg.GetProperties( );
foreach (XElement node in xx.Root.Descendants())
{
object obiect = Activator.CreateInstance(gg);
foreach (PropertyInfo property in pps)
{ if (property.Name == "nume" )
property.SetValue(obiect, node.Name.ToString(),null);
if (property.Name == "parinte")
property.SetValue(obiect, node.Parent.Name.ToString(), null);
}
foreach (XAttribute xa in node.Attributes())
{
string value="";
int value2=0;
{ if(xa.Name.ToString()!="rind" && xa.Name.ToString()!="col")
value = xa.Value;
else
value2 = int.Parse( xa.Value);
foreach (PropertyInfo property in pps)
{
if (property.Name == xa.Name.ToString())
{
if(xa.Name.ToString()=="rind" || xa.Name.ToString()=="col")
property.SetValue(obiect, value2, null);
else
property.SetValue(obiect, value, null);
break;
}
}
}
} collection.Add(obiect);
}
return collection;
}
the problem is that I can't loop through the properties.
I would like to create something like this:
public class blabla
{
public int property1{get;set;}
public int property2{get;set;}
}
and be able to do something like this
object1.property=1;
this is what i need:
I have a xml string that looks like this:
<xml>
<col1 label="label1" r="1" c="1"/>
<col2 label="label2" r="2" c="1"/>
<col3 label="label2" r="2" c="2"/>
< /xml>
i want to bind it to a datagrid.
the problem is that i don't know how many attributes i will have at runtime.
for the above example i could create a class like this:
public class blabla
{
public string labe{get;set;}
public int r{get;set;}
public int c{get;set;}
}
but as I said there can be many more attributes. that's why I need something dynamically.
At the same time I need to be able to iterate through the properties created
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

据我所知,您正在尝试将对象集合绑定到数据网格,但您不知道该对象在编译时会是什么样子。
这篇博文解决了这个问题:
http://blog.bodurov.com/如何绑定-Silverlight-DataGrid-From-IEnumerable-of-IDictionary/
如果我误解了您的问题,请告诉我。
As far as I can tell, you are trying to bind a collection of objects to a datagrid where you don't know what the object will look like at compile-time.
This blog post adresses that issue:
http://blog.bodurov.com/How-to-Bind-Silverlight-DataGrid-From-IEnumerable-of-IDictionary/
If I misunderstood your question, please let me know.