我如何在 C#(silverlight) 中创建一个动态类,我可以在其中循环属性

发布于 01-04 17:13 字数 5212 浏览 1 评论 0原文

这是我的代码:

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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

初心未许2025-01-11 17:13:40

据我所知,您正在尝试将对象集合绑定到数据网格,但您不知道该对象在编译时会是什么样子。

这篇博文解决了这个问题:
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.

断爱2025-01-11 17:13:40

我想说,最好的选择是将源 XML 转换为 DataSet 或 IEnumerable,然后将其绑定到网格。

I would say your best bet would be to transform the source XML to a DataSet or an IEnumerable and then bind that to your grid.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文