DropDownList 是 Web Forms 最常用的下拉選單控制項。資料來源可能來自陣列、資料庫、DataReader、DataSet 甚至自訂物件。本文系統整理五種主流綁定場景,涵蓋宣告式與程式碼後置雙重示範,並強調 IsPostBack 判斷、資源釋放等實務細節。
// 後置碼
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
var items = new List { "台北", "台中", "高雄" };
ddlCity.DataSource = items;
ddlCity.DataBind();
}
}
// 前台 .aspx
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ddlPriority.Items.Add(new ListItem("高", "3"));
ddlPriority.Items.Add(new ListItem("中", "2"));
ddlPriority.Items.Add(new ListItem("低", "1"));
}
}
適用於固定選項(如優先級、狀態碼),避免資料庫查詢開銷。
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
string connStr = ConfigurationManager.ConnectionStrings["DB"].ConnectionString;
using (var conn = new SqlConnection(connStr))
using (var cmd = new SqlCommand("SELECT DeptId, DeptName FROM Departments", conn))
{
conn.Open();
using (var dr = cmd.ExecuteReader())
{
while (dr.Read())
{
ddlDept.Items.Add(new ListItem(dr["DeptName"].ToString(), dr["DeptId"].ToString()));
}
}
}
}
}
優點:記憶體佔用低,適合大量資料;缺點:需手動管理連線生命週期,程式碼較冗長。
protected void BindDepartments()
{
string sql = "SELECT DeptId, DeptName FROM Departments WHERE IsActive = 1";
using (var da = new SqlDataAdapter(sql, connStr))
{
var ds = new DataSet();
da.Fill(ds, "Depts");
ddlDept.DataSource = ds.Tables["Depts"];
ddlDept.DataTextField = "DeptName"; // 顯示文字
ddlDept.DataValueField = "DeptId"; // 實際值
ddlDept.DataBind();
}
}
關鍵屬性:
DataTextField:對應顯示欄位DataValueField:對應值欄位(SelectedValue 取得)AppendDataBoundItems="true":保留手動加入的首項「請選擇」雖 DropDownList 少直接使用,但在 EditItemTemplate 中常見:
後置碼提供 GetRoles() 回傳 List<Role> 或 DataTable。
| 陷阱 | 後果 | 解決方案 |
|---|---|---|
| 未判斷 IsPostBack | 每次回傳重綁,導致使用者選擇被覆蓋 | 包裹在 if (!IsPostBack) 區塊 |
| DataReader 未關閉 | 連線洩漏、連線池耗盡 | 使用 using 區塊自動 Dispose |
| DataTextField/ValueField 拼錯 | 顯示空白或例外 | 對照 SQL 別名,區分大小寫 |
| 大量資料未分頁 | 下拉選單渲染緩慢、ViewState 膨脹 | 改用 AutoComplete / 搜尋式下拉元件 |
新專案建議採用 ASP.NET Core + Blazor / Razor Pages 搭配 select 標籤與 InputSelect<TValue>,或前端框架(Vue/React)元件,透過 Web API 非同步載入選項,體驗更佳。