當 GridView 欄位數量、顯示邏輯需在執行期決定 (如依設定檔、使用者權限),無法使用宣告式 `ITemplate 介面的動態欄位類別,在 InstantiateIn 中掛載 DataBinding 事件,實現每列資料的自訂繫結邏輯。
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();
}
}
| 階段 | 發生時機 | 關鍵物件 | 說明 |
|---|---|---|---|
| InstantiateIn | DataBind() 時,建立控制項樹 | container (TableCell) | 在每個儲存格建立 Label 並掛載 DataBinding 事件 |
| DataBinding 事件 | 每列資料繫結前 | sender (Label), NamingContainer (DataGridItem) | 透過 DataItem 取得該列 DataRowView,讀取欄位值決定顯示內容 |
| PreRender | 繫結完成後 | GridView | 產生最終 HTML |
InstantiateIn 依條件建立 TextBox、CheckBox、DropDownList 等IEditableTemplate 或手動處理 UpdateCommand 事件OnDataBinding 中設定 lbl.CssClass、lbl.ForeColorRepeater + ItemTemplate 避免 ViewState 膨脹新專案建議使用 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 時代實現動態欄位的標準模式。核心在於:
ITemplate.InstantiateIn 建立控制項並掛載事件DataBinding 事件中透過 NamingContainer.DataItem 存取當列資料TemplateColumn 加入 Columns 集合雖 WebForms 已非主流,但此模式展示了「模板方法 + 事件驅動」的經典設計思想,對理解現代框架的渲染管線同樣有價值。