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

ASP.NET DataGrid/GridView 動態產生欄位完全實現:ITemplate 模板類別與資料繫結事件

     編輯:關於C語言

前言

當 GridView 欄位數量、顯示邏輯需在執行期決定 (如依設定檔、使用者權限),無法使用宣告式 ``。解決方案:實作 ITemplate 介面的動態欄位類別,在 InstantiateIn 中掛載 DataBinding 事件,實現每列資料的自訂繫結邏輯。

DynamicColumn 完整實現

public class DynamicColumn : ITemplate
{
    private readonly string _columnName;  // 資料來源欄位名
    private readonly int _targetValue;    // 比對目標值

    public DynamicColumn(string columnName, int targetValue)
    {
        _columnName = columnName;
        _targetValue = targetValue;
    }

    // ITemplate 唯一必須實作方法
    public void InstantiateIn(Control container)
    {
        var lbl = new Label();
        lbl.DataBinding += OnDataBinding; // 掛載繫結事件
        container.Controls.Add(lbl);
    }

    // 資料繫結事件處理:每一列資料繫結時觸發
    private void OnDataBinding(object sender, EventArgs e)
    {
        var lbl = (Label)sender;
        var container = (DataGridItem)lbl.NamingContainer; // 取得 DataGridItem
        var dataItem = (DataRowView)container.DataItem;    // 取得該列資料列

        int cellValue = int.Parse(dataItem[_columnName].ToString());
        lbl.Text = (cellValue == _targetValue) ? "√" : "";
    }
}

使用方式:程式碼動態加入欄位

protected void Page_Load(object sender, EventArgs e)
{
    if (!IsPostBack)
    {
        // 假設從設定檔讀取欄位定義
        var columns = new[]
        {
            new { Name = "Status1", Target = 1, Header = "狀態一" },
            new { Name = "Status2", Target = 0, Header = "狀態二" }
        };

        foreach (var col in columns)
        {
            var templateCol = new TemplateColumn
            {
                HeaderText = col.Header,
                ItemTemplate = new DynamicColumn(col.Name, col.Target)
            };
            DataGrid1.Columns.Add(templateCol);
        }

        DataGrid1.DataSource = GetData(); // 回傳 DataTable/DataView
        DataGrid1.DataBind();
    }
}

核心機制解析

階段發生時機關鍵物件說明
InstantiateInDataBind() 時,建立控制項樹container (TableCell)在每個儲存格建立 Label 並掛載 DataBinding 事件
DataBinding 事件每列資料繫結前sender (Label), NamingContainer (DataGridItem)透過 DataItem 取得該列 DataRowView,讀取欄位值決定顯示內容
PreRender繫結完成後GridView產生最終 HTML

進階擴充方向

  • 多種控制項:InstantiateIn 依條件建立 TextBox、CheckBox、DropDownList 等
  • 雙向繫結:實作 IEditableTemplate 或手動處理 UpdateCommand 事件
  • 樣式動態化:OnDataBinding 中設定 lbl.CssClass、lbl.ForeColor
  • 效能優化:大量資料改用 Repeater + ItemTemplate 避免 ViewState 膨脹

現代替代方案 (ASP.NET Core / Blazor)

新專案建議使用 Razor 條件渲染或 Blazor 元件動態建構:

@foreach (var col in DynamicColumns)
{
    @col.Header
}
@foreach (var row in Data)
{
    
    @foreach (var col in DynamicColumns)
    {
        @(row[col.Name] == col.Target ? "√" : "")
    }
    
}

總結

ITemplate + DataBinding 事件是 ASP.NET WebForms 時代實現動態欄位的標準模式。核心在於:

  1. 實作 ITemplate.InstantiateIn 建立控制項並掛載事件
  2. 在 DataBinding 事件中透過 NamingContainer.DataItem 存取當列資料
  3. 程式碼動態建立 TemplateColumn 加入 Columns 集合

雖 WebForms 已非主流,但此模式展示了「模板方法 + 事件驅動」的經典設計思想,對理解現代框架的渲染管線同樣有價值。

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