枚举的多语言显示(2)——使用Attribute
还是jhh0111昨天关于枚举的双语显示问题的帖子的问题,有不少人跟贴询问使用Attribute的实现,于是刚才乘午间休息实现了一个,这里share一下。
主要框架还是和枚举的多语言显示里一样,对Enum包装了一个DataSource,唯一不同的是里面的每一个Item的DisplayValue采用从Attribute读出,所以这里就不再贴出EnumDataSource代码了(请参考枚举的多语言显示),这里仅仅列出和上篇不同的地方:
显然这里的静态方法是很重要的,通过它就可以访问枚举的额外信息了:
https://files.cnblogs.com/winkingzhang/Demo_2008_03_26.rar
主要框架还是和枚举的多语言显示里一样,对Enum包装了一个DataSource,唯一不同的是里面的每一个Item的DisplayValue采用从Attribute读出,所以这里就不再贴出EnumDataSource代码了(请参考枚举的多语言显示),这里仅仅列出和上篇不同的地方:
1public 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 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}
显然这里的静态方法是很重要的,通过它就可以访问枚举的额外信息了:
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)]
5public 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/// 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)]
5public 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}
1private 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
8public 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 this.comboBox1.DataSource = new EnumDataSource2<Sex>();
4 this.comboBox1.DisplayMember = "DisplayValue";
5 this.comboBox1.ValueMember = "Value";
6}
7
8public 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}
https://files.cnblogs.com/winkingzhang/Demo_2008_03_26.rar
To be the apostrophe which changed “Impossible” into “I’m possible”
----------------------------------------------------
WinkingZhang's Blog (http://winkingzhang.cnblogs.com)
GCDN(http://gcdn.grapecity.com/cs)