首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> ASP.NET 基礎 >> 關於ASP.NET

ASP.NET 伺服器控件開發基礎 (19):BaseDataList、Repeater 與列表控件深度解析

     編輯:關於ASP.NET

前言:資料綁定控件的分類與演進

ASP.NET 內建資料綁定控件按架構分為兩大家族:

  • 表格型家族:DataGrid (1.x) → GridView (2.0+),繼承 BaseDataList → DataBoundControl
  • 模板型家族:Repeater、DataList,繼承 Control / BaseDataList
  • 列表控件家族:DropDownList、ListBox、CheckBoxList、RadioButtonList、BulletedList,繼承 ListControl

本篇深度解析 BaseDataList 抽象類別、Repeater 靈活架構、ListControl 列表控件體系。

BaseDataList:表格型控件的共同基礎

BaseDataList 類別結構

核心特徵


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; }
}

設計模式啟示:Template Method Pattern

BaseDataList 定義了建立控件階層的演算法骨架:

  1. CreateControlHierarchy:建立 Header、Item、Separator、Footer 等控件樹
  2. PrepareControlHierarchy:資料繫結、套用樣式、事件綁定

子類別 (DataList, DataGrid/GridView) 只需實作具體細節,複用共同邏輯。

Repeater:極致輕量的模板控件

架構差異:為什麼 Repeater 不繼承 BaseDataList?

特性DataList/DataGridRepeater
基類BaseDataListControl (直接繼承)
佈局控制內建 Table/Flow 佈局完全由模板決定 (無預設佈局)
樣式屬性豐富的 Style 集合無 (完全靠 CSS/模板控制)
命令事件預定義 Edit/Update/Delete/Cancel僅 ItemCommand (通用)
DataKeyField支援不支援
效能較重 (建立大量 Style 物件)極輕量、渲染最快

Repeater 核心模板

Repeater 模板類型

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;
}

實戰:用 Repeater 模擬 DropDownList


<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 標籤,開發效率高。

ListControl:列表控件的統一基類

ListControl 繼承階層

繼承體系


System.Web.UI.WebControls.ListControl (abstract)
├── BulletedList (2.0 新增,項目符號列表)
├── CheckBoxList (核取方塊群組)
├── DropDownList (下拉選單)
├── ListBox (清單方塊)
└── RadioButtonList (選項按鈕群組)

ListControl 核心成員


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>純顯示、無選取互動、項目符號列表

擴展實戰:自訂 CheckBoxList 支援分組


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());
    }
}

選型指南:何時使用哪個控件?

  1. GridView:需求分頁、排序、編輯、複雜欄位、表格呈現 → 首選
  2. Repeater:高度客製化 HTML、極致效能、SEO 友善、無表格結構 → 首選
  3. DataList:重複佈局 (流式/表格)、需預定義命令事件、中等客製化 → 考慮
  4. ListView (3.5+):GridView 功能 + Repeater 彈性、支援群組模板、現代首選
  5. DropDownList/ListBox:標準選單需求 → 直接使用
  6. CheckBoxList/RadioButtonList:核取/單選群組、資料驅動選項 → 直接使用
  7. BulletedList:靜態/動態項目符號列表、無互動 → 直接使用

總結

ASP.NET 控件家族經過多版本演進,形成表格型 (GridView)、模板型 (Repeater/DataList/ListView)、列表型 (ListControl 子類)三大體系。BaseDataList 封裝表格佈局與樣式共性,Repeater 以極簡架構提供最大彈性,ListControl 統一列表選項管理邏輯。理解各控件架構定位與渲染差異,能根據需求做出最佳技術選型。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved