C#基础扎实的高手请进

时间:2020-11-30 11:27:06
有两个问题需向各位前辈请教:
1、我定义了一个实体类C,它有N个bool属性。然后在界面用代码生成N个的checkbox,checkbox的名称便是C类里的其中一个属性。有没有法子,我在遍历CheckBox的时候,知道它对应于哪个属性?数目太多,不想一个一个比较

2、我重写VS自带的ListBox控件,定义了一个listBoxItem来存放每一个条目,如果绑定的对象是dataTable或List<listBoxItem>,可以把其转换为listBoxItem对象,但如果是绑定其他未名称知道的实体集,如何转换呢?至今没找到好的解决法子

以上两个问题困扰了我2个晚上睡不好觉,如果您知道或有好的解决方式,还请告知。
谢谢!

6 个解决方案

#1


1、可以,用反射搞定,参见下面代码

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace CSDNConsoleTest
{
    class T_Test
    {
        int m_a;
        int m_b;

        public int a
        {
            get
            {
                return m_a;
            }
        }

        public int b
        {
            get
            {
                return m_b;
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {

            T_Test test = new T_Test();

            Type t = test.GetType();

            foreach (PropertyInfo p in t.GetProperties())
            {
                Console.WriteLine(p.Name);
            }
        }
    }
}

#2


第二个问题也是一样,
可以遍历你的结构中的所有属性,然后获取属性名,属性类型和属性值,
然后转换为DataTable,属性名对应于其中的一个列名,再用DataTable来
绑定就可以了。最近本来打算做个类似的例子,一直忙,还没来得及做。
下面是获取属性值的函数,我以前写的

        /// <summary>
        /// 获取属性值
        /// </summary>
        /// <param name="obj">要获取属性的对象</param>
        /// <param name="propertyName">属性名</param>
        /// <returns></returns>
        public static object GetPropertyValue(object obj, String propertyName, object[] index)
        {
            Type t = obj.GetType();
            PropertyInfo pi;

            if (index != null)
            {
                if (index.Length > 0)
                {

                    obj = GetPropertyValue(obj, propertyName, null);
                    t = obj.GetType();
                    propertyName = "Item";
                }
            }

            if (index != null)
            {
                Type[] types = new Type[index.Length];

                for (int i = 0; i < types.Length; i++)
                {
                    types[i] = index[i].GetType();
                }

                pi = t.GetProperty(propertyName, types);
            }
            else
            {
                pi = t.GetProperty(propertyName);
            }
            
            if (pi == null)
            {
                Exception e = new Exception(String.Format("Unknown Property Name = {0}", propertyName));
                throw (e);
            }


            return pi.GetValue(obj, index);
        }

#3


TO:eaglet(小鹰) 
谢谢!不过您的方法并没能解决我的问题!

第1个问题并不是要知道属性名称,而是知道属性名称后,如何赋值?像您的代码里,要对p.Name属性赋值!

第2个问题,微软的控件并不需转换,不知其内部是如何实现的...

#4


第一个问题改用哈希表存储就可以了;
第二个不太明白你的要求....

#5


设置属性值当然是可以的了,下面是代码

        /// <summary>   
        /// 设置属性值
        /// </summary>
        /// <param name="obj">设置属性的对象</param>
        /// <param name="propertyName">属性名</param>
        /// <param name="value">属性值</param>
        public static void SetPropertyValue(object obj, String propertyName, object value, object[] index)
        {
            Type t = obj.GetType();
            PropertyInfo pi;

            if (index != null)
            {
                if (index.Length > 0)
                {
                    obj = GetPropertyValue(obj, propertyName, null);
                    t = obj.GetType();
                    propertyName = "Item";
                }
            }

            if (index != null)
            {
                Type[] types = new Type[index.Length];

                for (int i = 0; i < types.Length; i++)
                {
                    types[i] = index[i].GetType();
                }

                pi = t.GetProperty(propertyName, types);
            }
            else
            {
                pi = t.GetProperty(propertyName);
            }

            if (pi == null)
            {
                Exception e = new Exception(String.Format("Unknown Property Name = {0}", propertyName));
                throw (e);
            }

            pi.SetValue(obj, value, index);
        }

#6


class a
{
   string _propertyname=""
   public propertyname
   {
      get{ return _propertyname;}
      set{ _propertyname=Value;}
   }
}

a class1=new a();
class1.propetyname="asdasdf";
PropertyDescriptor member = TypeDescriptor.GetProperties(class1)["propertyname"];
object oldvalue=member.GetValue(class1);
MessageBox.Show(oldvalue.ToString())
member.SetValue(class1, "newvalue");
MessageBox.Show(class1.propertyname);

#1


1、可以,用反射搞定,参见下面代码

using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;

namespace CSDNConsoleTest
{
    class T_Test
    {
        int m_a;
        int m_b;

        public int a
        {
            get
            {
                return m_a;
            }
        }

        public int b
        {
            get
            {
                return m_b;
            }
        }
    }

    class Program
    {
        static void Main(string[] args)
        {

            T_Test test = new T_Test();

            Type t = test.GetType();

            foreach (PropertyInfo p in t.GetProperties())
            {
                Console.WriteLine(p.Name);
            }
        }
    }
}

#2


第二个问题也是一样,
可以遍历你的结构中的所有属性,然后获取属性名,属性类型和属性值,
然后转换为DataTable,属性名对应于其中的一个列名,再用DataTable来
绑定就可以了。最近本来打算做个类似的例子,一直忙,还没来得及做。
下面是获取属性值的函数,我以前写的

        /// <summary>
        /// 获取属性值
        /// </summary>
        /// <param name="obj">要获取属性的对象</param>
        /// <param name="propertyName">属性名</param>
        /// <returns></returns>
        public static object GetPropertyValue(object obj, String propertyName, object[] index)
        {
            Type t = obj.GetType();
            PropertyInfo pi;

            if (index != null)
            {
                if (index.Length > 0)
                {

                    obj = GetPropertyValue(obj, propertyName, null);
                    t = obj.GetType();
                    propertyName = "Item";
                }
            }

            if (index != null)
            {
                Type[] types = new Type[index.Length];

                for (int i = 0; i < types.Length; i++)
                {
                    types[i] = index[i].GetType();
                }

                pi = t.GetProperty(propertyName, types);
            }
            else
            {
                pi = t.GetProperty(propertyName);
            }
            
            if (pi == null)
            {
                Exception e = new Exception(String.Format("Unknown Property Name = {0}", propertyName));
                throw (e);
            }


            return pi.GetValue(obj, index);
        }

#3


TO:eaglet(小鹰) 
谢谢!不过您的方法并没能解决我的问题!

第1个问题并不是要知道属性名称,而是知道属性名称后,如何赋值?像您的代码里,要对p.Name属性赋值!

第2个问题,微软的控件并不需转换,不知其内部是如何实现的...

#4


第一个问题改用哈希表存储就可以了;
第二个不太明白你的要求....

#5


设置属性值当然是可以的了,下面是代码

        /// <summary>   
        /// 设置属性值
        /// </summary>
        /// <param name="obj">设置属性的对象</param>
        /// <param name="propertyName">属性名</param>
        /// <param name="value">属性值</param>
        public static void SetPropertyValue(object obj, String propertyName, object value, object[] index)
        {
            Type t = obj.GetType();
            PropertyInfo pi;

            if (index != null)
            {
                if (index.Length > 0)
                {
                    obj = GetPropertyValue(obj, propertyName, null);
                    t = obj.GetType();
                    propertyName = "Item";
                }
            }

            if (index != null)
            {
                Type[] types = new Type[index.Length];

                for (int i = 0; i < types.Length; i++)
                {
                    types[i] = index[i].GetType();
                }

                pi = t.GetProperty(propertyName, types);
            }
            else
            {
                pi = t.GetProperty(propertyName);
            }

            if (pi == null)
            {
                Exception e = new Exception(String.Format("Unknown Property Name = {0}", propertyName));
                throw (e);
            }

            pi.SetValue(obj, value, index);
        }

#6


class a
{
   string _propertyname=""
   public propertyname
   {
      get{ return _propertyname;}
      set{ _propertyname=Value;}
   }
}

a class1=new a();
class1.propetyname="asdasdf";
PropertyDescriptor member = TypeDescriptor.GetProperties(class1)["propertyname"];
object oldvalue=member.GetValue(class1);
MessageBox.Show(oldvalue.ToString())
member.SetValue(class1, "newvalue");
MessageBox.Show(class1.propertyname);