手把手教你写Ajax驱动的DataGrid控件(二)
点击次数:24 次 发布日期:2008-11-26 09:55:24 作者:源代码网
|
源代码网推荐 做任何事情,都需要一个思想作为指导,我们的控件当然也不例外。 源代码网推荐 1. 控件的名字(我们姑且叫他AjaxGrid吧,后文将一直用此名称) 源代码网推荐 2. 面向控件的使用人员(即开发人员),我们要求代码尽可能得精简,API(包括JavaScript)丰富 源代码网推荐 3. 面向最终用户,我们要求响应迅速、界面精美并且符合使用习惯(本地化) 源代码网推荐 居于以上几点,我们进入主题,开始我们的编码之旅。 源代码网推荐 源代码网推荐 三. 编写控件代码 源代码网推荐 Asp.net的用户控件非常令人兴奋,它比任何OO宣传的代码重用都要来的实际,因为任何一个人即便OO了,他还是有可能在下一个项目中重写这些代码,而控件,不管是初学还是老手,重用是必然的。你不需要掌握太多的服务器控件开发方法,因为我们的控件要实现需求,并不会使用到控件的一些更高深的东东,如模版控件、回调、数据绑定和状态管理等,我们需要的只是重写Render方法。 源代码网推荐 为什么要重写Render方法,因为我们要在页面输出自己的Html,而我们控件的本来面貌就是一个Html table。可是还有一个问题,我们需要翻页和过滤数据,这就要求我们的table必须重绘,毫无疑问,重绘的数据当然来自服务器。刷新页面是常用的办法,但是别忘了,我们做的可是Ajax表格哦^_^。也许你会想到XmlRequest,正是,我们其实都很容易想到它,不用刷新的问题解决了。可还有一个问题,服务器要是没有保留表格的数据源怎么办?我们在以后再次请求它生成符合要求的表格时它却告诉你它把数据源给丢了,那样可行不通。其实问题也很简单,我们就让它保留数据源供以后翻页和过滤数据使用,直到我们确定不再使用这个数据源(AjaxGrid销毁),再将其“丢掉”。 源代码网推荐 下面将逐步实现上面的几点。 源代码网推荐 1. 为控件指定数据源,并保存它直到不再需要为止 源代码网推荐 我们选择采用System.Data.DataTable作为我们的最终数据源,因为它便于排序、翻页、和过滤数据。但是,控件的使用者(开发人员)可不希望为了使用我们的控件每次都去生成一个DataTable,那怎么办?既然别人不愿意干,那就我们自己动手了。我们发现,可以绑定到服务器控件的数据源,都会实现IListSource 或IEnumerable 接口,也就是说,我们只要检查开发人员为控件指定的数据源是否实现了上述两个接口中的一个,(如果没有呢?这个问题还要问吗,给他点异常看看他下次保证就不敢了),再将它们转化为DataTable。代码如下: 源代码网推荐 using System; 源代码网推荐 using System.Data; 源代码网推荐 using System.Collections; 源代码网推荐 using System.ComponentModel; 源代码网推荐 源代码网推荐 namespace Wfyfngu.Web.UI 源代码网推荐 { 源代码网推荐 /**//// <summary> 源代码网推荐 /// DataSourceHelper 的摘要说明。 源代码网推荐 /// </summary> 源代码网推荐 internal class DataSourceHelper 源代码网推荐 { 源代码网推荐 源代码网推荐 源代码网推荐 private static IEnumerable ResolveDataSource(object dataSource, string dataMember) 源代码网推荐 { 源代码网推荐 // 如果是 IListSource 源代码网推荐 if(dataSource is IListSource) 源代码网推荐 { 源代码网推荐 IListSource listSource = (IListSource)dataSource; 源代码网推荐 IList list = listSource.GetList(); 源代码网推荐 // 源代码网推荐 if(listSource.ContainsListCollection) 源代码网推荐 { 源代码网推荐 ITypedList typedList = (ITypedList)list; 源代码网推荐 PropertyDescriptorCollection collection = typedList.GetItemProperties(new PropertyDescriptor[0]); 源代码网推荐 if(collection.Count == 0) 源代码网推荐 throw new Exception("ListSource without DataMembers"); 源代码网推荐 源代码网推荐 PropertyDescriptor descriptor = null; 源代码网推荐 if (dataMember == null || dataMember == string.Empty) 源代码网推荐 { 源代码网推荐 descriptor = collection[0]; 源代码网推荐 } 源代码网推荐 else 源代码网推荐 { 源代码网推荐 descriptor = collection.Find(dataMember, true); 源代码网推荐 } 源代码网推荐 if(descriptor == null) 源代码网推荐 throw new Exception("ListSource missing DataMember"); 源代码网推荐 源代码网推荐 object listItem = list[0]; 源代码网推荐 object member = descriptor.GetValue(listItem); 源代码网推荐 源代码网推荐 if (member == null || !(member is IEnumerable)) 源代码网推荐 throw new Exception("ListSource missing DataMember"); 源代码网推荐 源代码网推荐 return (IEnumerable)member; 源代码网推荐 } 源代码网推荐 else 源代码网推荐 { 源代码网推荐 return (IEnumerable)list; 源代码网推荐 } 源代码网推荐 } 源代码网推荐 if(dataSource is IEnumerable) 源代码网推荐 { 源代码网推荐 return (IEnumerable)dataSource; 源代码网推荐 } 源代码网推荐 源代码网推荐 throw new Exception("None IListSource or IEnumerable."); 源代码网推荐 } 源代码网推荐 源代码网推荐 /**//// <summary> 源代码网推荐 /// 将实现了IListSource 和 IEnumerable的数据源转换为 DataTable 源代码网推荐 /// </summary> 源代码网推荐 /// <param name="dataSource"></param> 源代码网推荐 /// <returns></returns> 源代码网推荐 internal static DataTable ConventToDataTable(object dataSource) 源代码网推荐 { 源代码网推荐 if(dataSource == null) 源代码网推荐 return new DataTable(); 源代码网推荐 IEnumerable ie = ResolveDataSource(dataSource, null); 源代码网推荐 DataTable table = new DataTable(); 源代码网推荐 int colIndex = 0; 源代码网推荐 ArrayList rows = new ArrayList(); 源代码网推荐 foreach(object item in ie) 源代码网推荐 { 源代码网推荐 源代码网推荐 if(item is DataRowView) 源代码网推荐 { 源代码网推荐 table = ((DataRowView)item).DataView.Table; 源代码网推荐 for(int i=0; i<table.Columns.Count; i++) 源代码网推荐 table.Columns[i].ColumnName = "f"+i.ToString(); 源代码网推荐 return table; 源代码网推荐 } 源代码网推荐 // 源代码网推荐 table.Columns.Add("f"+(colIndex++).ToString()); 源代码网推荐 rows.Add(item); 源代码网推荐 } 源代码网推荐 object[] o = new object[rows.Count]; 源代码网推荐 for(int i=0; i<o.Length; i++) 源代码网推荐 o[i] = rows[i]; 源代码网推荐 table.Rows.Add(o); 源代码网推荐 return table; 源代码网推荐 } 源代码网推荐 源代码网推荐 } 源代码网推荐 } 源代码网推荐 做人要厚道,请注明转自酷网动力(www.ASPCOOL.COM)。 源代码网推荐 源代码网供稿. |
