ASP.NET 內建資料綁定控件按架構分為兩大家族:
DataGrid (1.x) → GridView (2.0+),繼承 BaseDataList → DataBoundControlRepeater、DataList,繼承 Control / BaseDataListDropDownList、ListBox、CheckBoxList、RadioButtonList、BulletedList,繼承 ListControl本篇深度解析 BaseDataList 抽象類別、Repeater 靈活架構、ListControl 列表控件體系。
public abstract class BaseDataList : WebControl, INamingContainer
{
// 佈局屬性
public RepeatDirection RepeatDirection { get; set; } // Horizontal/Vertical
public RepeatLayout RepeatLayout { get; set; } // Table/Flow/UnorderedList
public int RepeatColumns { get; set; }
// 樣式屬性集合
public TableItemStyle ItemStyle { get; }
public TableItemStyle AlternatingItemStyle { get; }
public TableItemStyle SelectedItemStyle { get; }
public TableItemStyle EditItemStyle { get; }
public TableItemStyle HeaderStyle { get; }
public TableItemStyle FooterStyle { get; }
public TableItemStyle SeparatorStyle { get; }
// 抽象方法:留給子類別實作控件階層建立與準備
protected abstract void CreateControlHierarchy(bool useDataSource);
protected abstract void PrepareControlHierarchy();
// 預定義命令事件
public event CommandEventHandler ItemCommand;
public event DataListCommandEventHandler EditCommand;
public event DataListCommandEventHandler UpdateCommand;
public event DataListCommandEventHandler DeleteCommand;
public event DataListCommandEventHandler CancelCommand;
// 資料鍵欄位
public string DataKeyField { get; set; }
public DataKeyCollection DataKeys { get; }
}
BaseDataList 定義了建立控件階層的演算法骨架:
CreateControlHierarchy:建立 Header、Item、Separator、Footer 等控件樹PrepareControlHierarchy:資料繫結、套用樣式、事件綁定子類別 (DataList, DataGrid/GridView) 只需實作具體細節,複用共同邏輯。
| 特性 | DataList/DataGrid | Repeater |
|---|---|---|
| 基類 | BaseDataList | Control (直接繼承) |
| 佈局控制 | 內建 Table/Flow 佈局 | 完全由模板決定 (無預設佈局) |
| 樣式屬性 | 豐富的 Style 集合 | 無 (完全靠 CSS/模板控制) |
| 命令事件 | 預定義 Edit/Update/Delete/Cancel | 僅 ItemCommand (通用) |
| DataKeyField | 支援 | 不支援 |
| 效能 | 較重 (建立大量 Style 物件) | 極輕量、渲染最快 |
public class Repeater : Control, INamingContainer
{
// 五大核心模板
[TemplateContainer(typeof(RepeaterItem))]
public ITemplate HeaderTemplate { get; set; }
[TemplateContainer(typeof(RepeaterItem))]
public ITemplate ItemTemplate { get; set; }
[TemplateContainer(typeof(RepeaterItem))]
public ITemplate AlternatingItemTemplate { get; set; }
[TemplateContainer(typeof(RepeaterItem))]
public ITemplate SeparatorTemplate { get; set; }
[TemplateContainer(typeof(RepeaterItem))]
public ITemplate FooterTemplate { get; set; }
// 無 DataKeyField、無預定義命令事件、無樣式屬性
// 僅提供 ItemCommand 通用事件
public event RepeaterCommandEventHandler ItemCommand;
}
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:Northwind %>"
SelectCommand="SELECT TOP 3 ProductID, ProductName FROM Products">
</asp:SqlDataSource>
<asp:Repeater ID="Repeater1" runat="server" DataSourceID="SqlDataSource1">
<HeaderTemplate>
<select id="CustomSelect">
</HeaderTemplate>
<ItemTemplate>
<option value="<%# Eval("ProductID") %>"><%# Eval("ProductName") %></option>
</ItemTemplate>
<FooterTemplate>
</select>
</FooterTemplate>
</asp:Repeater>
<!-- 原生 DropDownList 對照 -->
<asp:DropDownList ID="DropDownList2" runat="server"
DataTextField="ProductName" DataValueField="ProductID"
DataSourceID="SqlDataSource1">
</asp:DropDownList>
Repeater 靈活但需手寫 HTML,適合高度客製化 UI;DropDownList 封裝好 select 標籤,開發效率高。
System.Web.UI.WebControls.ListControl (abstract)
├── BulletedList (2.0 新增,項目符號列表)
├── CheckBoxList (核取方塊群組)
├── DropDownList (下拉選單)
├── ListBox (清單方塊)
└── RadioButtonList (選項按鈕群組)
public abstract class ListControl : WebControl, INamingContainer, IPostBackDataHandler
{
// 資料繫結核心屬性
public string DataTextField { get; set; } // 顯示文字欄位
public string DataValueField { get; set; } // 值欄位
public string DataTextFormatString { get; set; } // 格式化字串
// 項目集合
public ListItemCollection Items { get; }
// 選取狀態
public ListItem SelectedItem { get; }
public int SelectedIndex { get; set; }
public string SelectedValue { get; set; }
// 事件
public event EventHandler SelectedIndexChanged;
// 核心方法
protected abstract void PerformDataBinding(IEnumerable dataSource);
protected virtual void OnSelectedIndexChanged(EventArgs e) { ... }
public virtual bool LoadPostData(string postDataKey, NameValueCollection postCollection) { ... }
public virtual void RaisePostDataChangedEvent() { ... }
}
| 控件 | 渲染 HTML | 適用場景 |
|---|---|---|
| DropDownList | <select><option>...</option></select> | 單選、空間有限、選項較多 |
| ListBox | <select size="4">...</select> | 單選/多選、需同時顯示多選項 |
| CheckBoxList | <table><tr><td><input type="checkbox"><label>...</td></tr></table> | 多選、需清晰顯示所有選項 |
| RadioButtonList | <table>...<input type="radio">... | 單選、選項較少、需並排顯示 |
| BulletedList | <ul><li>...</li></ul> 或 <ol> | 純顯示、無選取互動、項目符號列表 |
public class GroupedCheckBoxList : CheckBoxList
{
public string DataGroupField { get; set; } // 分組欄位
protected override void PerformDataBinding(IEnumerable dataSource)
{
base.PerformDataBinding(dataSource);
if (string.IsNullOrEmpty(DataGroupField)) return;
// 重新組織 Items:插入分組標題
List newItems = new List();
string currentGroup = null;
foreach (ListItem item in Items)
{
// 假設 DataItem 保留在某處可取得分組值
// 實際需覆寫 CreateControlHierarchy 或使用 DataBound 事件
string groupValue = GetGroupValue(item);
if (groupValue != currentGroup)
{
if (currentGroup != null)
newItems.Add(new ListItem("", "") { Enabled = false }); // 分隔線
newItems.Add(new ListItem(groupValue, "") { Enabled = false, Attributes = { ["class"] = "group-header" } });
currentGroup = groupValue;
}
newItems.Add(item);
}
Items.Clear();
Items.AddRange(newItems.ToArray());
}
}
ASP.NET 控件家族經過多版本演進,形成表格型 (GridView)、模板型 (Repeater/DataList/ListView)、列表型 (ListControl 子類)三大體系。BaseDataList 封裝表格佈局與樣式共性,Repeater 以極簡架構提供最大彈性,ListControl 統一列表選項管理邏輯。理解各控件架構定位與渲染差異,能根據需求做出最佳技術選型。