DarkangleFormBinder
本文附带的代码在Asp.Net 2.0下面调试通过
先讲一下背景:
在.Net多层结构程序中,我们会使用一些O/R MAPPING的工具将数据库表或视图映射成实体数据模形用于封装数据,开发中我们可能经常会写这样的代码,例如,我们有一个Student的表,包含一些字段,如Name, Sex, Age, Grade, Height, Weight, ChooseClass.....
我们假设有一个录入学生信息的表单,我们可能会写这样的一些代码,在前台上:
姓名:<asp:TextBox ID="Name" runat="Server" /> 年龄:<asp:TextBox ID="Age" runat = "Server" /> 年级:<aspropDownList ID="Grade" runat = "server" /> 课外活动: <asp:CheckBoxList ID="ChooseClass" runat= "server" />
后台呢:
我们需要先构造一个新的对象:
Student s= new Student();
然后设置它的属性:
s.Name = Name.Text; s.Age = Age.Text; s.Grade = Grade.SelectedValue;
然后保存到后台数据库
如果是读取一条记录出来显示在页面上,我们可能先要取得一个对象实例:
Student s = bll.GetStudentById(id); Name.Text = s.Name; Age.Text = s.Age; Grade.Items.FindByValue(s.Grade).Selected = true;
上面标红的部分代码可能会非常多,尤其是在字段比较多的时候,设定这些值就非常麻烦,不但不能漏掉,还要做类型转换等,稍有不小心就会出错.
现在我们可以利用反射的方法将这些属性自动与控件值关联起来,这样就不用手动地编写这些代码了.
具体内容请看我的示例工程文件.注意要在Web.Config中加上控件的引用路径.
这些代码参考了MSDN上面的内容,但是原来的代码有BUG,并且不支持可以多项选择的控件.我在这里加入了两个控件,分别是DarkangleCheckBoxList和DarkangleListBox 这两个控件支持将多项选择的属性以逗号分开的方式存储于数据库字段中. 比如,学生.课余活动 = "照象,游泳,足球",不需要写额外的代码即可直接绑定到多项选择控件.
目前支持的绑定控件有:Label,TextBox,CheckBox,DarkangleCheckBoxList,DarkangleListBox(如果您只需要单项选择,则可以使用自带的ListBox控件),ListBox,DropDownList, RadioButton,RadioButtonList,日历控件.
希望我写的东西对您的开发有所帮助.
Good luck~~~~;)
源代码与示例打包下载
应版主大人要求,把源码贴出来的,其实我提供的下载包里面是有源码的,就在类工程里面,随便也把原来那个老外的也帖上来,我修改了部分内容,原来那个代码运行起来也是有问题的。
先帖我的:
using System; using System.Web; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using System.Reflection;
namespace Darkangle { public class FormBinder { public static void BindObjectToControls(object obj, Control container) { if (obj == null) return; Type objType = obj.GetType(); PropertyInfo[] objPropertiesArray = objType.GetProperties(); foreach (PropertyInfo objProperty in objPropertiesArray) { Control control = container.FindControl(objProperty.Name); bool success = false; bool isCustom = false; if (control is DarkangleListBox) { DarkangleListBox listBox = (DarkangleListBox)control; string propertyValue = objProperty.GetValue(obj, null).ToString(); listBox.SetListValue(propertyValue); isCustom = true; } if (control is DarkangleCheckBoxList) { DarkangleCheckBoxList checkBoxList = (DarkangleCheckBoxList)control; string propertyValue = objProperty.GetValue(obj, null).ToString(); checkBoxList.SetListValue(propertyValue); isCustom = true; } if (!isCustom) { 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 { Type controlType = control.GetType(); PropertyInfo[] controlPropertiesArray = controlType.GetProperties(); success = FindAndSetControlProperty(obj, objProperty, control, controlPropertiesArray, "Checked", typeof(bool)); if (!success) { success = FindAndSetControlProperty(obj, objProperty, control, controlPropertiesArray, "SelectedDate", typeof(DateTime)); if (success) FindAndSetControlProperty(obj, objProperty, control, controlPropertiesArray, "VisibleDate", typeof(DateTime)); } if (!success) success = FindAndSetControlProperty(obj, objProperty, control, controlPropertiesArray, "Value", typeof(String)); if (!success) success = FindAndSetControlProperty(obj, objProperty, control, controlPropertiesArray, "Text", typeof(String)); } } } } private static bool FindAndSetControlProperty(object obj, PropertyInfo objProperty, Control control, PropertyInfo[] controlPropertiesArray, string propertyName, Type type) { foreach (PropertyInfo controlProperty in controlPropertiesArray) { if (controlProperty.Name == propertyName && controlProperty.PropertyType == type) { controlProperty.SetValue(control, Convert.ChangeType(objProperty.GetValue(obj, null), type), null); return true; } } return false; } public static void BindControlsToObject(object obj, Control container) { if (obj == null) return; Type objType = obj.GetType(); PropertyInfo[] objPropertiesArray = objType.GetProperties(); foreach (PropertyInfo objProperty in objPropertiesArray) { bool success = false; bool isCustom = false; Control control = container.FindControl(objProperty.Name); if (control is DarkangleListBox) { DarkangleListBox listBox = (DarkangleListBox)control; if (listBox.SelectedIndex > -1) objProperty.SetValue(obj, Convert.ChangeType(listBox.GetListValue(), objProperty.PropertyType), null); isCustom = true; } if (control is DarkangleCheckBoxList) { DarkangleCheckBoxList checkBoxList = (DarkangleCheckBoxList)control; if (checkBoxList.SelectedIndex > -1) objProperty.SetValue(obj, Convert.ChangeType(checkBoxList.GetListValue(), objProperty.PropertyType), null); isCustom = true; } if (!isCustom) { if (control is ListControl) { ListControl listControl = (ListControl)control; if (listControl.SelectedItem != null) objProperty.SetValue(obj, Convert.ChangeType(listControl.SelectedItem.Value, objProperty.PropertyType), null); } else { Type controlType = control.GetType(); PropertyInfo[] controlPropertiesArray = controlType.GetProperties();
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)); } } } } private static bool FindAndGetControlProperty(object obj, PropertyInfo objProperty, Control control, PropertyInfo[] controlPropertiesArray, string propertyName, Type type) { foreach (PropertyInfo controlProperty in controlPropertiesArray) { if (controlProperty.Name == propertyName && controlProperty.PropertyType == type) { try { objProperty.SetValue(obj, Convert.ChangeType(controlProperty.GetValue(control, null), objProperty.PropertyType), null); return true; } catch { return false; } } } return false; } } }
这两个是我护展出来的控件:
using System; using System.Collections.Generic; using System.Text; using System.Web.UI.WebControls;
namespace System.Web.UI.WebControls { public class DarkangleCheckBoxList : CheckBoxList { public void SetListValue(string listValue) { if (listValue == null || listValue.Trim() == string.Empty) return; string[] valueList = listValue.Split(new char[] { ',' }); if (valueList.Length == 0) return; for (int i = 0; i < valueList.Length; i++) { if (valueList[i].Length != 0 && valueList[i] != string.Empty) this.Items.FindByValue(valueList[i]).Selected = true; } } public string GetListValue() { StringBuilder sb = new StringBuilder(); for (int i = 0; i < this.Items.Count; i++) { if (this.Items[i].Selected) sb.Append(this.Items[i].Value + ","); } return sb.Remove(sb.Length - 1, 1).ToString(); } } public class DarkangleListBox : ListBox { public void SetListValue(string listValue) { if (listValue == null || listValue.Trim() == string.Empty) return; string[] valueList = listValue.Split(new char[] { ',' }); if (valueList.Length == 0) return; for (int i = 0; i < valueList.Length; i++) { if (valueList[i].Length != 0 && valueList[i] != string.Empty) this.Items.FindByValue(valueList[i]).Selected = true; } } public string GetListValue() { StringBuilder sb = new StringBuilder(); for (int i = 0; i < this.Items.Count; i++) { if (this.Items[i].Selected) sb.Append(this.Items[i].Value + ","); } return sb.Remove(sb.Length-1,1).ToString(); } } }
经典论坛讨论: http://bbs.blueidea.com/thread-2707666-1-1.html
出处:蓝色理想
责任编辑:blue
◎进入论坛网络编程版块参加讨论
|