主要框架还是和枚举的多语言显示里一样,对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)。
2

3

4

5

6

7

8

9

10

11

12

显然这里的静态方法是很重要的,通过它就可以访问枚举的额外信息了:
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
}
使用示例如下:
2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

127

128

129

130

131

132

133

134

135

136

137

138

139

140

141

142

143

144

145

146

147

148

149

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
}
你可以从这里下载本篇中的相关示例代码:
2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

https://files.cnblogs.com/winkingzhang/Demo_2008_03_26.rar