在 ASP.NET Web Forms / MVC 中,將 `enum` 綁定至 `DropDownList`、`RadioButtonList` 或在 GridView 中顯示枚舉描述是極常見的需求。本文整理三個實用技巧:GridView 顯示枚舉文字、通用枚舉綁定輔助方法 (支援 Description 屬性)、前端直接轉換。
假設資料表欄位 `PerpaidCard_Status` 為 `int`,對應枚舉 `EnumBidCardStatus`。
<asp:Label ID="lblStatus" runat="server"
Text='<%# (CN80s.DDPM.Model.Enum.EnumBidCardStatus)(int)Eval("PerpaidCard_Status") %>' />
原理:`Eval` 取得 `int` → 強制轉型為 `int` → 再轉型為枚舉類型 → `ToString()` 自動輸出枚舉成員名稱。
<asp:Label ID="lblStatus" runat="server"
Text='<%# EnumHelper.GetDescription((CN80s.DDPM.Model.Enum.EnumBidCardStatus)(int)Eval("PerpaidCard_Status")) %>' />
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Web.UI.WebControls;
public static class EnumHelper
{
///
/// 取得枚舉的 Description 屬性值,若無則回傳成員名稱
///
public static string GetDescription(Enum value)
{
if (value == null) return string.Empty;
var field = value.GetType().GetField(value.ToString());
if (field == null) return value.ToString();
var attr = field.GetCustomAttribute();
return attr?.Description ?? value.ToString();
}
///
/// 將枚舉轉為 ListItem 集合,可選擇是否加入「全部」選項
///
public static List ToListItems(Type enumType, bool includeAllOption = false, string allText = "-- 全部 --", string allValue = "")
{
if (!enumType.IsEnum) throw new ArgumentException("型別必須為枚舉", nameof(enumType));
var list = new List();
if (includeAllOption) list.Add(new ListItem(allText, allValue));
foreach (var field in enumType.GetFields(BindingFlags.Public | BindingFlags.Static))
{
var value = field.GetRawConstantValue();
var descAttr = field.GetCustomAttribute();
string text = descAttr?.Description ?? field.Name;
list.Add(new ListItem(text, value.ToString()));
}
return list;
}
///
/// 直接綁定至 DropDownList/ListBox/RadioButtonList/CheckBoxList
///
public static void BindToListControl(ListControl control, Type enumType, bool includeAllOption = false, string allText = "-- 全部 --", string allValue = "")
{
control.DataSource = ToListItems(enumType, includeAllOption, allText, allValue);
control.DataTextField = "Text";
control.DataValueField = "Value";
control.DataBind();
}
///
/// 取得指定值的 Description (適用於資料庫存 int 值)
///
public static string GetDescriptionByValue(Type enumType, int value)
{
var name = Enum.GetName(enumType, value);
if (name == null) return value.ToString();
var field = enumType.GetField(name);
var attr = field?.GetCustomAttribute();
return attr?.Description ?? name;
}
}
// 1. 簡單綁定
EnumHelper.BindToListControl(ddlBidCardType, typeof(EnumBidCardType), true);
// 2. 手動控制 (需自訂排序/過濾)
var items = EnumHelper.ToListItems(typeof(EnumBidCardType), true);
ddlBidCardType.DataSource = items;
ddlBidCardType.DataBind();
// 3. GridView 中使用
//
// 4. 後端取得描述
string desc = EnumHelper.GetDescriptionByValue(typeof(EnumBidCardType), 2);
using System.ComponentModel;
public enum EnumBidCardType
{
[Description("一般標案")]
Normal = 1,
[Description("緊急標案")]
Urgent = 2,
[Description("邀標案件")]
Invited = 3,
[Description("協商採購")]
Negotiated = 4
}
優點:程式碼與顯示文字分離,支援多國語系 (搭配 Resource 檔)、維護容易。
public class LocalizedDescriptionAttribute : DescriptionAttribute
{
private readonly string _resourceKey;
private readonly Type _resourceType;
public LocalizedDescriptionAttribute(string resourceKey, Type resourceType)
{
_resourceKey = resourceKey;
_resourceType = resourceType;
}
public override string Description
{
get
{
var prop = _resourceType.GetProperty(_resourceKey, BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
return prop?.GetValue(null)?.ToString() ?? _resourceKey;
}
}
}
// 使用
public enum OrderStatus
{
[LocalizedDescription("Order_Pending", typeof(Resources.Enums))]
Pending = 1,
[LocalizedDescription("Order_Shipped", typeof(Resources.Enums))]
Shipped = 2
}
private static readonly Dictionary> _enumCache = new Dictionary>();
private static readonly object _lock = new object();
public static List GetCachedListItems(Type enumType, bool includeAllOption)
{
var key = enumType;
if (_enumCache.TryGetValue(key, out var cached)) return cached;
lock (_lock)
{
if (_enumCache.TryGetValue(key, out cached)) return cached;
var list = ToListItems(enumType, includeAllOption);
_enumCache[key] = list;
return list;
}
}
| 場景 | 推薦做法 |
|---|---|
| GridView/Repeater 顯示枚舉文字 | `EnumHelper.GetDescriptionByValue(typeof(EnumType), (int)Eval("Field"))` |
| DropDownList 綁定枚舉 | `EnumHelper.BindToListControl(ddl, typeof(EnumType), true)` |
| 後端根據 int 值取得描述 | `EnumHelper.GetDescriptionByValue(typeof(EnumType), intValue)` |
| 多國語系專案 | 自訂 `LocalizedDescriptionAttribute` + Resource 檔 |
| 高頻呼叫 | 靜態快取 `Dictionary |
建立通用 `EnumHelper` 類別並納入專案共用函式庫,能大幅減少重複代碼,統一枚舉顯示邏輯,提升維護性。