轉自 http://www.cnblogs.com/wfyfngu/archive/2007/10/09/917789.html
二. 指導思想
做任何事情,都需要一個思想作為指導,我們的控制項當然也不例外。
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;
}
}
}
>>待續!控制項源碼及簡單介紹請登陸 http://www.codeassistant.net/wfygrid/<<