还是jhh0111昨天
关于枚举的双语显示问题的帖子的问题,有不少人跟贴询问使用Attribute的实现,于是刚才乘午间休息实现了一个,这里share一下。
主要框架还是和
枚举的多语言显示里一样,对Enum包装了一个DataSource,唯一不同的是里面的每一个Item的DisplayValue采用从Attribute读出,所以这里就不再贴出EnumDataSource代码了(请参考枚举的多语言显示),这里仅仅列出和上篇不同的地方:
1
public string DisplayValue
2

{
3
get
4
{
5
Dictionary<CultureInfo, EnumItemDescriptionAttribute> disc =
6
EnumItemDescriptionAttribute.GetDisplayValues(_value, typeof(EnumType));
7
CultureInfo currentUICulute = Thread.CurrentThread.CurrentUICulture;
8
if (disc.ContainsKey(currentUICulute))
9
return disc[currentUICulute].Description;
10
return _value.ToString();
11
}
12
}
这里取值是通过EnumItemDescriptionAttribute上的静态Helper方法提供,如果找到对应Culture的Attribute就应用,否则返回默认值(枚举的ToString)。
显然这里的静态方法是很重要的,通过它就可以访问枚举的额外信息了:
1
/**//// <summary>
2
/// Define the item of special enum used attribute, you can use it mulitple for multi-descript one enum item.
3
/// </summary>
4
[AttributeUsage(AttributeTargets.Field, AllowMultiple=true)]
5
public class EnumItemDescriptionAttribute : Attribute
6

{
7
/**//// <summary>
8
/// A cache store, because accessing Attribute is according to reflection, it cost too much
9
/// So I add a cache, which based on special enum Type.
10
/// </summary>
11
private static readonly Dictionary<Type, Dictionary<object, Dictionary<CultureInfo, EnumItemDescriptionAttribute>>> _cache =
12
new Dictionary<Type,Dictionary<object, Dictionary<CultureInfo, EnumItemDescriptionAttribute>>>();
13
/**//// <summary>
14
/// the culture of Description
15
/// </summary>
16
private CultureInfo _culture;
17
/**//// <summary>
18
/// the description content.
19
/// </summary>
20
private string _description;
21
22
/**//// <summary>
23
/// Constructor a new <see cref="EnumItemDescriptionAttribute"/> with special culture name and description.
24
/// </summary>
25
/// <param name="cultureName">the name of special culture, like en-US, zh-CN etc.</param>
26
/// <param name="description">the content of Descroption</param>
27
public EnumItemDescriptionAttribute(string cultureName, string description)
28
: this(CultureInfo.GetCultureInfo(cultureName), description)
29
{
30
}
31
32
/**//// <summary>
33
/// Constructor a new <see cref="EnumItemDescriptionAttribute"/> with special culture id and description.
34
/// </summary>
35
/// <param name="cultureId">the ID of special culture, like 1033 etc.</param>
36
/// <param name="description">the content of Descroption</param>
37
public EnumItemDescriptionAttribute(int cultureId, string description)
38
: this(CultureInfo.GetCultureInfo(cultureId), description)
39
{
40
}
41
42
/**//// <summary>
43
/// Internal constructor.
44
/// </summary>
45
/// <param name="culture">special <see cref="CultureInfo"/></param>
46
/// <param name="description">the content of Descroption</param>
47
private EnumItemDescriptionAttribute(CultureInfo culture, string description)
48
{
49
_culture = culture;
50
_description = description;
51
}
52
53
/**//// <summary>
54
/// Gets the <see cref="CultureInfo"/> for current decription.
55
/// </summary>
56
public CultureInfo Culture
57
{
58
get
{ return _culture; }
59
}
60
61
/**//// <summary>
62
/// Gets the description content.
63
/// </summary>
64
public string Description
65
{
66
get
{ return _description; }
67
}
68
69
/**//// <summary>
70
/// Gets all <see cref="EnumItemDescriptionAttribute"/>
71
/// for special enum value: <paramref name="value"/> and special enum type: <paramref name="enumType"/>.
72
/// </summary>
73
/// <param name="value">the value of special enum</param>
74
/// <param name="enumType">the enum type of special enum</param>
75
/// <returns>All attributes attatched on special enum value.</returns>
76
public static Dictionary<CultureInfo, EnumItemDescriptionAttribute> GetDisplayValues(object value, Type enumType)
77
{
78
if (enumType == null || !enumType.IsEnum)
79
{
80
throw new NotSupportedException("enumType is not a Enum");
81
}
82
if (value == null || !Enum.IsDefined(enumType, value))
83
{
84
throw new ArgumentException("value is not defined in " + enumType.FullName);
85
}
86
87
return GetDisplayValuesImp(value, enumType);
88
}
89
90
/**//// <summary>
91
/// Gets the <see cref="EnumItemDescriptionAttribute"/> for special enum value: <paramref name="value"/>,
92
/// special enum type: <paramref name="enumType"/> and special culture.
93
/// </summary>
94
/// <param name="value">the value of special enum</param>
95
/// <param name="enumType">the enum type of special enum</param>
96
/// <param name="culture">special culture for item description.</param>
97
/// <returns>The attributes attatched on special enum value.</returns>
98
public static string GetDisplayValue(object value, Type enumType, CultureInfo culture)
99
{
100
if (enumType == null || !enumType.IsEnum)
101
{
102
throw new NotSupportedException("enumType is not a Enum");
103
}
104
if (value == null || !Enum.IsDefined(enumType, value))
105
{
106
throw new ArgumentException("value is not defined in " + enumType.FullName);
107
}
108
109
if (culture == null)
110
return value.ToString();
111
112
Dictionary<CultureInfo, EnumItemDescriptionAttribute> disc = GetDisplayValuesImp(value, enumType);
113
if (disc.ContainsKey(culture))
114
return disc[culture].Description;
115
return value.ToString();
116
}
117
118
/**//// <summary>
119
/// Gets all <see cref="EnumItemDescriptionAttribute"/>
120
/// for special enum value: <paramref name="value"/> and special enum type: <paramref name="enumType"/>.
121
/// </summary>
122
/// <param name="value">the value of special enum</param>
123
/// <param name="enumType">the enum type of special enum</param>
124
/// <returns>All attributes attatched on special enum value.</returns>
125
private static Dictionary<CultureInfo, EnumItemDescriptionAttribute> GetDisplayValuesImp(object value, Type enumType)
126
{
127
if (!_cache.ContainsKey(enumType))
128
{
129
Dictionary<object, Dictionary<CultureInfo, EnumItemDescriptionAttribute>> displayValues =
130
new Dictionary<object, Dictionary<CultureInfo, EnumItemDescriptionAttribute>>();
131
foreach (Enum item in Enum.GetValues(enumType))
132
{
133
Dictionary<CultureInfo, EnumItemDescriptionAttribute> descriptions =
134
new Dictionary<CultureInfo, EnumItemDescriptionAttribute>();
135
FieldInfo enumField = enumType.GetField(item.ToString());
136
if (enumField != null)
137
{
138
foreach (EnumItemDescriptionAttribute desc
139
in enumField.GetCustomAttributes(typeof(EnumItemDescriptionAttribute), true))
140
{
141
descriptions.Add(desc.Culture, desc);
142
}
143
}
144
displayValues.Add(item, descriptions);
145
}
146
_cache.Add(enumType, displayValues);
147
}
148
149
return _cache[enumType][value];
150
}
151
}
使用示例如下:
1
private void Form1_Load(object sender, EventArgs e)
2

{
3
this.comboBox1.DataSource = new EnumDataSource2<Sex>();
4
this.comboBox1.DisplayMember = "DisplayValue";
5
this.comboBox1.ValueMember = "Value";
6
}
7
8
public enum Sex
9

{
10
[EnumItemDescription("zh-CN", "男")]
11
[EnumItemDescription("ja", "男性")]
12
[EnumItemDescription("de", "Männliche")]
13
Male,
14
[EnumItemDescription("zh-CN", "女")]
15
[EnumItemDescription("ja", "女性")]
16
[EnumItemDescription("de", "Weibliche")]
17
Female
18
}
你可以从这里下载本篇中的相关示例代码:
http://files.cnblogs.com/winkingzhang/Demo_2008_03_26.rar