DarkangleFormBinder
本文附帶的代碼在Asp.Net 2.0下面調(diào)試通過
先講一下背景:
在.Net多層結(jié)構(gòu)程序中,我們會(huì)使用一些O/R MAPPING的工具將數(shù)據(jù)庫表或視圖映射成實(shí)體數(shù)據(jù)模形用于封裝數(shù)據(jù),開發(fā)中我們可能經(jīng)常會(huì)寫這樣的代碼,例如,我們有一個(gè)Student的表,包含一些字段,如Name, Sex, Age, Grade, Height, Weight, ChooseClass.....
我們假設(shè)有一個(gè)錄入學(xué)生信息的表單,我們可能會(huì)寫這樣的一些代碼,在前臺(tái)上:
姓名:<asp:TextBox ID="Name" runat="Server" /> 年齡:<asp:TextBox ID="Age" runat = "Server" /> 年級(jí):<aspropDownList ID="Grade" runat = "server" /> 課外活動(dòng): <asp:CheckBoxList ID="ChooseClass" runat= "server" />
后臺(tái)呢:
我們需要先構(gòu)造一個(gè)新的對(duì)象:
Student s= new Student();
然后設(shè)置它的屬性:
s.Name = Name.Text; s.Age = Age.Text; s.Grade = Grade.SelectedValue;
然后保存到后臺(tái)數(shù)據(jù)庫
如果是讀取一條記錄出來顯示在頁面上,我們可能先要取得一個(gè)對(duì)象實(shí)例:
Student s = bll.GetStudentById(id); Name.Text = s.Name; Age.Text = s.Age; Grade.Items.FindByValue(s.Grade).Selected = true;
上面標(biāo)紅的部分代碼可能會(huì)非常多,尤其是在字段比較多的時(shí)候,設(shè)定這些值就非常麻煩,不但不能漏掉,還要做類型轉(zhuǎn)換等,稍有不小心就會(huì)出錯(cuò).
現(xiàn)在我們可以利用反射的方法將這些屬性自動(dòng)與控件值關(guān)聯(lián)起來,這樣就不用手動(dòng)地編寫這些代碼了.
具體內(nèi)容請看我的示例工程文件.注意要在Web.Config中加上控件的引用路徑.
這些代碼參考了MSDN上面的內(nèi)容,但是原來的代碼有BUG,并且不支持可以多項(xiàng)選擇的控件.我在這里加入了兩個(gè)控件,分別是DarkangleCheckBoxList和DarkangleListBox 這兩個(gè)控件支持將多項(xiàng)選擇的屬性以逗號(hào)分開的方式存儲(chǔ)于數(shù)據(jù)庫字段中. 比如,學(xué)生.課余活動(dòng) = "照象,游泳,足球",不需要寫額外的代碼即可直接綁定到多項(xiàng)選擇控件.
目前支持的綁定控件有:Label,TextBox,CheckBox,DarkangleCheckBoxList,DarkangleListBox(如果您只需要單項(xiàng)選擇,則可以使用自帶的ListBox控件),ListBox,DropDownList, RadioButton,RadioButtonList,日歷控件.
希望我寫的東西對(duì)您的開發(fā)有所幫助.
Good luck~~~~;)
源代碼與示例打包下載
應(yīng)版主大人要求,把源碼貼出來的,其實(shí)我提供的下載包里面是有源碼的,就在類工程里面,隨便也把原來那個(gè)老外的也帖上來,我修改了部分內(nèi)容,原來那個(gè)代碼運(yùn)行起來也是有問題的。
先帖我的:
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; } } }
這兩個(gè)是我護(hù)展出來的控件:
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(); } } }
經(jīng)典論壇討論: http://bbs.blueidea.com/thread-2707666-1-1.html
出處:藍(lán)色理想
責(zé)任編輯:blue
◎進(jìn)入論壇網(wǎng)絡(luò)編程版塊參加討論
|