1.定义一个存储枚举的显示名称的定制特性:

class EnumShowNameAttribute : Attribute
/// <summary>
/// 枚举的显示名称
/// </summary>
[global::System.AttributeUsage(AttributeTargets.Field, Inherited = false, AllowMultiple = false)]
public sealed class EnumShowNameAttribute : Attribute
{
/// <summary>
/// 显示名称
/// </summary>
public string ShowName { get; private set; }
/// <summary>
/// 构造枚举的显示名称
/// </summary>
/// <param name="showName">显示名称</param>
public EnumShowNameAttribute(string showName)
{
this.ShowName = showName;
}
}
2.为每个枚举的成员添加此定制特性。如:

Code
/// <summary>
/// 性别
/// </summary>
public enum Sex
{
/// <summary>
/// 男
/// </summary>
[EnumShowName("男")]
Man=0,
/// <summary>
/// 女
/// </summary>
[EnumShowName("女")]
Woman=1,
}
3.写显示枚举名称、绑定控件的扩展方法。
显示枚举名称方法(ToShowName())的思路本来很简单:根据枚举值获取其EnumShowNameAttribute定制特性的ShowName属性值。但我这里的代码并不少,主要用来处理以下几点:
1.缓存。由于用反射的方式获取值性能不好。于是这里用了一个Dictionary<string,string>来缓存枚举值对应的ShowName,Key是[枚举类的FullName].[枚举值的ToString],Value是ShowName值。那么只是第一次访问的时候需要反射,以后都从缓存里取就行了。
2.FlagsAttribute标记的枚举。此标志表示这个枚举按位排列。那么不缓存它,且需要拿输入值与枚举的成员一个一个比较。
另:绑定的时候应尊重控件的AppendDataBoundItems属性,给使用时更多选择。

Code
static private Dictionary<string, string> _cacheEnumShowNamedDic = new Dictionary<string, string>();


/**//// <summary>
/// 输出枚举的ShowName,需要枚举声明EnumShowNameAttribute
/// </summary>
/// <param name="en">待输出的枚举</param>
/// <returns></returns>
static public string ToShowName(this Enum en)

{
return ToShowName(en, false, ",");
}


/**//// <summary>
/// 输出枚举的ShowName,需要枚举声明EnumShowNameAttribute
/// </summary>
/// <param name="en">待输出的枚举</param>
/// <param name="exceptionIfNotSuccess">未成功是否抛出异常</param>
/// <param name="flagsSeparator">Flags类型输出时的间隔符</param>
/// <returns></returns>
static public string ToShowName(this Enum en, bool exceptionIfFail,string flagsSeparator)

{
string showName;
string enFullName = GetEnumFullName(en);

// 先在缓存中找
if (!_cacheEnumShowNamedDic.TryGetValue(enFullName, out showName))

{
// 获取枚举类型
Type enumType = en.GetType();

// 查看其是否Flags
object[] flagsAtts = enumType.GetCustomAttributes(typeof(FlagsAttribute), false);

// 有Flags,按位处理,不缓存
if (flagsAtts != null && flagsAtts.Length > 0)

{
long currentVal = Convert.ToInt64(en);
StringBuilder sb = new StringBuilder();

string[] names = Enum.GetNames(enumType);
string zeroString = "";

foreach (string name in names)

{
long val = Convert.ToInt64(Enum.Parse(enumType, name));

// val为0,则跳过
if (val == 0)

{
object[] atts = enumType.GetField(name).GetCustomAttributes(typeof(EnumShowNameAttribute), false);
if (atts.Length > 0)

{
// 找到,设置
zeroString = ((EnumShowNameAttribute)atts[0]).ShowName;
}
continue;
}

// 比较
if ((val & currentVal) == val)

{
// 加间隔符
if (sb.Length != 0)

{
sb.Append(flagsSeparator);
}

// 加上定制特性值
object[] atts = enumType.GetField(name).GetCustomAttributes(typeof(EnumShowNameAttribute), false);
if (atts.Length > 0)

{
// 找到,设置
sb.Append(((EnumShowNameAttribute)atts[0]).ShowName);
}
else

{
// 没找到定制特性,参数指定抛出异常则抛出异常
if (exceptionIfFail)

{
throw new InvalidOperationException(string.Format("此枚举{0}未定义EnumShowNameAttribute", enFullName));
}

sb.Append(name);
}
}
}

// 输出
if (sb.Length > 0)

{
return sb.ToString();
}
return zeroString;
}
// 无Flags
else

{
// 找字段
FieldInfo fieldInfo = enumType.GetField(en.ToString());
if (fieldInfo == null)

{
throw new InvalidOperationException(string.Format("非完整枚举{0}", enFullName));
}

// 找定制特性
object[] atts = fieldInfo.GetCustomAttributes(typeof(EnumShowNameAttribute), false);
if (atts.Length > 0)

{
// 找到,设置
showName = ((EnumShowNameAttribute)atts[0]).ShowName;
lock (_cacheEnumShowNamedDic)

{
_cacheEnumShowNamedDic[enFullName] = showName;
}
}
else

{
// 没找到定制特性,参数指定抛出异常则抛出异常
if (exceptionIfFail)

{
throw new InvalidOperationException(string.Format("此枚举{0}未定义EnumShowNameAttribute", enFullName));
}

// 否则直接输出本身的ToString
return en.ToString();
}
}
}

return showName;
}


/**//// <summary>
/// 获取枚举的全名
/// </summary>
/// <param name="en"></param>
/// <returns></returns>
static private string GetEnumFullName(Enum en)

{
return en.GetType().FullName + "." + en.ToString();
}


/**//// <summary>
/// 给ListControl绑定枚举值
/// </summary>
/// <typeparam name="T">枚举类型</typeparam>
/// <param name="listControl">待绑定的控件</param>
static public void BindEnum<T>(this System.Web.UI.WebControls.ListControl listControl)
where T : struct

{
// 获取类型
Type type = typeof(T);
if (!type.IsEnum)

{
throw new InvalidOperationException("类型必须是枚举:" + type.FullName);
}

// 获取枚举成员
Array values = Enum.GetValues(type);

// 绑定值
if (!listControl.AppendDataBoundItems)

{
listControl.Items.Clear();
}
foreach (Enum item in values)

{
listControl.Items.Add(new System.Web.UI.WebControls.ListItem(item.ToShowName(), item.ToString()));
}
}

4.使用。直接在枚举上ToShowName就可以得到显示的名称,在ListControl(DropDownList继承此类)用BindEnum方法绑定枚举。如:
this.ddlTest.BindEnum<Sex>();
string str = Sex.Man.ToShowName();
注:有多语言需求的项目和大项目,不推荐使用这种方案,而建议将显示的文字存储在单独的文件中。