做项目开发的时候,大家应该经常都会遇到一个表里面的很多个字段的情况吧.在之前我接触的一个项目,有一个表有20多个字段.要向表中添加记录,和将一条数据绑定到页面上都要写很多代码.如:下面是一个用户表的添加
        User user = new User();
        user.Name = this.txt_Name.Text; 
        user.Re = this.txt_Re.Text;
        user.Age = int.Parse(this.txt_Age.Text);
        user.Type=this.txt_Type.SelectedValue; 
        user.Time=DateTime.Parse(this.txt_Time.Text);
        new Test().SaveOrUpdate(user);
将表里面的数据绑定到控件里面如下
        User user=(User) new test().Get(typeof(User),"1");
        txt_Name.Text=user.Name;
        txt_Re.Text=user.Re;
        txt_Age.Text=user.Age.ToString();
        txt_Type.SelectedValue=txt_Type.Items.FindByValue(user.Type);
        txt_Time.Text=User.Time.ToString("yyyy-MM-dd");
上面的列子,数据类型不对我们得进行转换,下拉列表还要进行绑定.当然字段比较少,还不容易怎么出错,如果字段多了,这样一个一个的写太老火了,而且还容易忘记一些,或者把一些数据绑定错,或者忘了ToString().思路是这样的: 
一、对于网页中控件的命名规为 "txt_实体类的字段名";
二、遍历页面中的所有控件,使用反射将控件的值赋给对象。和将对象的属性值绑定到控件上。下面是要用到的一些方法    /**//// <summary>
    /// 字符串首字母大写
    /// </summary>
    /// <param name="s"></param>
    /// <returns></returns>
    public static string ToProperCase(string s)
    {
        string revised = "";
        if (s.Length > 0)
        {
            revised = s.Trim();
            revised = revised.Substring(0, 1).ToUpper() + revised.Substring(1).ToLower();
        }
        return revised;
    }    /**//// <summary>
    /// 设置对象属性的值
    /// </summary>
    public static void SetProperty(object obj, string name, object value)
    {
        PropertyInfo propertyInfo = obj.GetType().GetProperty(name);
        object objValue = Convert.ChangeType(value, propertyInfo.PropertyType);
        propertyInfo.SetValue(obj, objValue, null);
    }
    
    /**//// <summary>
    /// 获取对象属性的值
    /// </summary>
    public static object GetProperty(object obj, string name)
    {
        //bindingFlags
        PropertyInfo propertyInfo = obj.GetType().GetProperty(name);
        return propertyInfo.GetValue(obj, null);
    }
将控件的值绑定到对象上面。         for (int i = 0; i < Page.Controls.Count; i++)
        {
            SetControlValue(Controls[i], "txt_",ref user);  
        }
    /**//// <summary>
    /// 设置对象的值
    /// </summary>
    private void SetObjectValue(Control page, string str,ref object obj)
    {
        foreach (Control content in page.Controls)
        {
            if (content.Controls.Count > 0)
            {
                SetObjectValue(content, str,ref obj);
            }
            if (content.ID != null)
             {
                 string contentID = content.ID.ToLower();
                if (contentID.Replace(str, "") != contentID.ToLower())
                {
                    SetProperty(obj, ToProperCase(contentID.Replace(str, "")),
                                                   GetProperty(content,"Text")
                                               );
                }
            }
        }
    }
(上面的Text是TextBox控件的属性,对于下拉列表框也可以使用这个属性获取选定项的值,所以就不用去判断了,最开始我还去判断类型:)将对象的值绑定到控件上面
        for (int i = 0; i < Page.Controls.Count; i++)
        {
            SetControlValue(Controls[i], "txt_", user);
        }/**//// <summary>
    /// 设置控件的值
    /// </summary>
    private void SetControlValue(Control page, string str, object obj)
    {
        foreach (Control content in page.Controls)
        {
            if (content.Controls.Count > 0)
            {
                SetControlValue(content, str, obj);
            }
            if (content.ID != null)
            {
                string contentID = content.ID.ToLower();
                if (contentID.Replace(str, "") != contentID.ToLower())
                {
                    if (content.GetType() != typeof(DropDownList))
                    {
                        SetProperty(content, "Text",
                                                    GetProperty(obj, ToProperCase(contentID.Replace(str, "")))
                                                   );
                    }
                    else
                    {
                        SetDropDownListItem((DropDownList)content, (string)ReflectionUtil.GetProperty(obj, ToProperCase(contentID.Replace(str, ""))));
                    }
                }
            }
        } 
    }主要的代码就上面这些,你可以将这些放到公用的类库里,以后遇到字段多的表我们也就不用怕了.
我的博客人气太差了,放在上面都没有什么人看的,个人感觉做项目时这种方法很方便,特别是一个表字段太多的情况.只是要遍历一下页面控件,速度可能会慢一点.你们可以再加一些判断,对像DataGrid里面的就不需要再遍历了().复制过来代码颜色都没有了,给你们个地址:http://www.cnblogs.com/snryang/archive/2008/03/22/1117974.html

解决方案 »

  1.   

    MARK
      

  2.   

    反射性能是有影响,但是可以忽略不计。
    实际上在绑定DataSource到实体列表的时候就用了反射,多用一次也没太大差别。
      

  3.   

    给lz一个建议,通过自定义Attribute自动生成绑定列可能会更方便些。
      

  4.   

    反正tag可以用,直接把字段名填里面就行了
    然后遍历一遍就行了
      

  5.   

    sorry,以为是绑定到grid上了,原来是单个对象取值。
    这样的话还是按lz的方法比较好。
      

  6.   

    把User做成DataSource,然后,直接用自带的数据绑定就可以了(一句代码都不用写,只要在IDE上操作)需要灵活的话,倾向于反射+配置(特性或Xml)+Emit联合使用,同时保证灵活和高效
      

  7.   

    呵呵,LS说的是,我专门为此做了一个叫做DataBoundHolder的控件。
      

  8.   

    把User做成DataSource,然后,直接用自带的数据绑定就可以了(一句代码都不用写,只要在IDE上操作) 需要灵活的话,倾向于反射+配置(特性或Xml)+Emit联合使用,同时保证灵活和高效
      

  9.   

    说句实话,java的JSF也就是反射赋值。思想差不多,通过html标签结合反射完成展现和提取。很多同学说性能,这个是个问题。但是这个问题是个双刃剑。不能片面而论。
      

  10.   

    20多个字段就嫌多啊,而且还会出错,这只能说coding方面做的有点那个啊。
    简单的就是最好的,不反对楼主这种方法,但我觉得这种绑定本来是一件很简单的coding,只要细心些就OK了,
    非要自己整的这么复杂,而且性能方面还会有影响。
    呵呵,我选择一个一个写,直观,易懂,而且易维护。
    个人看法呵呵。
      

  11.   


    一个页面里80%左右的控件都与数据库字段相关,
    可以把这些控件放在一个Panel里面,只循环查找Panel里面的控件,性能影响应该能降到最低.
    呵呵,对于字段少的表,我也会选择手写.
      

  12.   

    修改不了帖子,做了一个简单的示例,下载地址:
    http://www.cnblogs.com/Files/snryang/Demo.rar
      

  13.   


    /**////  <summary>
        /// 字符串首字母大写
        ///  </summary>
        ///  <param name="s"> </param>
        ///  <returns> </returns>
        public static string ToProperCase(string s)
        {
            string revised = "";
            if (s.Length > 0)
            {
                revised = s.Trim();
                revised = revised.Substring(0, 1).ToUpper() + revised.Substring(1).ToLower();
            }
            return revised;
        }    /**////  <summary>
        /// 设置对象属性的值
        ///  </summary>
        public static void SetProperty(object obj, string name, object value)
        {
            PropertyInfo propertyInfo = obj.GetType().GetProperty(name);
            object objValue = Convert.ChangeType(value, propertyInfo.PropertyType);
            propertyInfo.SetValue(obj, objValue, null);
        }
        
        /**////  <summary>
        /// 获取对象属性的值
        ///  </summary>
        public static object GetProperty(object obj, string name)
        {
            //bindingFlags
            PropertyInfo propertyInfo = obj.GetType().GetProperty(name);
            return propertyInfo.GetValue(obj, null);
        }
    将控件的值绑定到对象上面。
             for (int i = 0; i  < Page.Controls.Count; i++)
            {
                SetControlValue(Controls[i], "txt_",ref user);  
            }
        /**////  <summary>
        /// 设置对象的值
        ///  </summary>
        private void SetObjectValue(Control page, string str,ref object obj)
        {
            foreach (Control content in page.Controls)
            {
                if (content.Controls.Count > 0)
                {
                    SetObjectValue(content, str,ref obj);
                }
                if (content.ID != null)
                 {
                     string contentID = content.ID.ToLower();
                    if (contentID.Replace(str, "") != contentID.ToLower())
                    {
                        SetProperty(obj, ToProperCase(contentID.Replace(str, "")),
                                                       GetProperty(content,"Text")
                                                   );
                    }
                }
            }
        }
    (上面的Text是TextBox控件的属性,对于下拉列表框也可以使用这个属性获取选定项的值,所以就不用去判断了,最开始我还去判断类型:)将对象的值绑定到控件上面
            for (int i = 0; i  < Page.Controls.Count; i++)
            {
                SetControlValue(Controls[i], "txt_", user);
            }/**////  <summary>
        /// 设置控件的值
        ///  </summary>
        private void SetControlValue(Control page, string str, object obj)
        {
            foreach (Control content in page.Controls)
            {
                if (content.Controls.Count > 0)
                {
                    SetControlValue(content, str, obj);
                }
                if (content.ID != null)
                {
                    string contentID = content.ID.ToLower();
                    if (contentID.Replace(str, "") != contentID.ToLower())
                    {
                        if (content.GetType() != typeof(DropDownList))
                        {
                            SetProperty(content, "Text",
                                                        GetProperty(obj, ToProperCase(contentID.Replace(str, "")))
                                                       );
                        }
                        else
                        {
                            SetDropDownListItem((DropDownList)content, (string)ReflectionUtil.GetProperty(obj, ToProperCase(contentID.Replace(str, ""))));
                        }
                    }
                }
            } 
        }
      

  14.   


    using System;
    using System.Web;
    using System.Web.UI;
    using System.Web.UI.HtmlControls;
    using System.Web.UI.WebControls;
    using System.Reflection;namespace DyerToolbox {
    /// <summary>
    /// A class with two static methods <see cref="BindObjectToControls"/> and <see cref="BindControlsToObject"/>
    /// used to bind the values of and object's properties with web <see cref="Control"/>s that have their
    /// ID property set to the name of the object property.
    /// </summary>
    public class FormBinding {
    /// <summary>
    /// Binds an object's properties to <see cref="Control"/>s with the same ID as the propery name. 
    /// </summary>
    /// <param name="obj">The object whose properties are being bound to forms Controls</param>
    /// <param name="container">The control in which the form Controls reside (usually a Page or ContainerControl)</param>
    public static void BindObjectToControls(object obj, Control container) {
    if (obj == null) return;

    // Get the properties of the business object
    //
    Type objType = obj.GetType();
    PropertyInfo[] objPropertiesArray = objType.GetProperties(); foreach (PropertyInfo objProperty in objPropertiesArray) { Control control = container.FindControl(objProperty.Name);

    // handle ListControls (DropDownList, CheckBoxList, RadioButtonList)
    //
    if (control is ListControl) {
    ListControl listControl = (ListControl) control;
    string propertyValue = objProperty.GetValue(obj, null).ToString();
    ListItem listItem = listControl.Items.FindByValue(propertyValue);
    if (listItem != null) listItem.Selected = true;

    } else {
    // get the properties of the control
    //
    Type controlType = control.GetType();
    PropertyInfo[] controlPropertiesArray = controlType.GetProperties(); // test for common properties
    //
    bool success = false;
    success = FindAndSetControlProperty(obj, objProperty, control, controlPropertiesArray, "Checked", typeof(bool) );

    if (!success) 
    success = FindAndSetControlProperty(obj, objProperty, control, controlPropertiesArray, "SelectedDate", typeof(DateTime) ); if (!success) 
    success = FindAndSetControlProperty(obj, objProperty, control, controlPropertiesArray, "Value", typeof(String) );

    if (!success) 
    success = FindAndSetControlProperty(obj, objProperty, control, controlPropertiesArray, "Text", typeof(String) );

    }
    }
    }

    /// <summary>
    /// Looks for a property name and type on a control and attempts to set it to the value in an object's property 
    /// of the same name.
    /// </summary>
    /// <param name="obj">The object whose properties are being retrieved</param>
    /// <param name="objProperty">The property of the object being retrieved</param>
    /// <param name="control">The control whose ID matches the object's property name.</param>
    /// <param name="controlPropertiesArray">An array of the control's properties</param>
    /// <param name="propertyName">The name of the Control property being set</param>
    /// <param name="type">The correct type for the Control property</param>
    /// <returns>Boolean for whether the property was found and set</returns>
    private static bool FindAndSetControlProperty(object obj, PropertyInfo objProperty, Control control, PropertyInfo[] controlPropertiesArray, string propertyName, Type type) {
    // iterate through control properties
    //
    foreach (PropertyInfo controlProperty in controlPropertiesArray) {
    // check for matching name and type
    //
    if (controlProperty.Name == propertyName && controlProperty.PropertyType == type) {
    // set the control's property to the business object property value
    //
    controlProperty.SetValue(control, Convert.ChangeType( objProperty.GetValue(obj, null), type) , null);
    return true;
    }
    }
    return false;
    } /// <summary>
    /// Binds your the values in <see cref="Control"/>s to a business object.
    /// </summary>
    /// <param name="obj">The object whose properties are being bound to Control values</param>
    /// <param name="container">The control in which the form Controls reside (usually a Page or ContainerControl)</param>
    public static void BindControlsToObject(object obj, Control container) {
    if (obj == null) return;

    // Get the properties of the business object
    //
    Type objType = obj.GetType();
    PropertyInfo[] objPropertiesArray = objType.GetProperties(); foreach (PropertyInfo objProperty in objPropertiesArray) { Control control = container.FindControl(objProperty.Name);
    if (control is ListControl) {
    ListControl listControl = (ListControl) control;
    if (listControl.SelectedItem != null)
    objProperty.SetValue(obj, Convert.ChangeType(listControl.SelectedItem.Value,objProperty.PropertyType), null); } else {
    // get the properties of the control
    //
    Type controlType = control.GetType();
    PropertyInfo[] controlPropertiesArray = controlType.GetProperties(); // test for common properties
    //
    bool success = false;
    success = FindAndGetControlProperty(obj, objProperty, control, controlPropertiesArray, "Checked", typeof(bool) ); if (!success) 
    success = FindAndGetControlProperty(obj, objProperty, control, controlPropertiesArray, "SelectedDate", typeof(DateTime) ); if (!success) 
    success = FindAndGetControlProperty(obj, objProperty, control, controlPropertiesArray, "Value", typeof(String) ); if (!success) 
    success = FindAndGetControlProperty(obj, objProperty, control, controlPropertiesArray, "Text", typeof(String) );
    }
    }
    } /// <summary>
    /// Looks for a property name and type on a control and attempts to set it to the value in an object's property 
    /// of the same name.
    /// </summary>
    /// <param name="obj">The object whose properties are being set</param>
    /// <param name="objProperty">The property of the object being set</param>
    /// <param name="control">The control whose ID matches the object's property name.</param>
    /// <param name="controlPropertiesArray">An array of the control's properties</param>
    /// <param name="propertyName">The name of the Control property being retrieved</param>
    /// <param name="type">The correct type for the Control property</param>
    /// <returns>Boolean for whether the property was found and retrieved</returns>
    private static bool FindAndGetControlProperty(object obj, PropertyInfo objProperty, Control control, PropertyInfo[] controlPropertiesArray, string propertyName, Type type) {
    // iterate through control properties
    //
    foreach (PropertyInfo controlProperty in controlPropertiesArray) {
    // check for matching name and type
    //
    if (controlProperty.Name == "Text" && controlProperty.PropertyType == typeof(String)) {
    // set the control's property to the business object property value
    //
    try {
    objProperty.SetValue(control, Convert.ChangeType( controlProperty.GetValue(obj, null), objProperty.PropertyType) , null);
    return true;
    } catch {
    // the data from the form control could not be converted to objProperty.PropertyType
    //
    return false;
    }
    }
    }
    return false;
    }
    }
    }
      

  15.   

    感觉不是很好吧..
    写个code生成器比这样还有用吧?
      

  16.   

    java框架中大量的使用了反射机制.
      

  17.   

    学习!eAo-亿奥网 http://www.jmeao.com