控件中国网现已改版,您看到的是老版本网站的镜像,系统正在为您跳转到新网站首页,请稍候.......
中国最专业的商业控件资讯网产品咨询电话:023-67870900 023-67871946
产品咨询EMAIL:SALES@COMPONENTCN.COM

枚举的多语言显示

作者:葡萄城 出处:葡萄城 2010年09月01日 阅读:

关于枚举类型的多语言显示,其实就是Globalization的问题。解决方案当然不止一种,这里介绍一种可用性和扩展性的比较好的通用方法。

 

显然这里自己去实现自定义格式化,即通过IFormatable、IFormatProvider、ICustomFormatter等接口已达到Globalization有点小题大作了,而另外一个很容易想到的点是通过DiaplayMember实现显示值得自定义(对于简单Binding,例如ComboBox、ListBox等只用重载ToString就可以了)。

 

首先,我们希望Binding整个枚举类型的每一个值,也就是说,我们需要把这个枚举的所有值变成一个数据源,为了实现这一点,我们可以使用Enum上的helper方法Enum.GetValues(Type)来返回一个对所有值得枚举,然后依次添加到IList对象或者IListSource接口即可。

 
 
01 if (!typeof(EnumType).IsEnum)
02 {
03     throw new NotSupportedException("Can not support type: " + typeof(EnumType).FullName);
04     // It's better use resource version as below.
05     // throw new NotSupportedException(SR.GetString("TYPE_NOT_SUPPORT",  typeof(EnumType).FullName));
06 }
07   
08 // Use Enum helper enumerator list all enum values and add to current context.
09 foreach (EnumType value in Enum.GetValues(typeof(EnumType)))
10 {
11     //TODO: add each value to IList
12     base.Add(new EnumAdapter(value));
13 }
 
 

然后,取到了值,由于我们希望自定义Binding显示,那么需要对枚举值进行封装,而在这个封装里面,我们可以实现多语言的支持。

01 /// <summary>
02 ///   Enum value adapter, used to get values from each Cultures.
03 /// </summary>
04 public sealed class EnumAdapter
05 {
06     /**//// <summary>
07     ///   Storage the actual Enum value.
08     /// </summary>
09     private EnumType _value;
10   
11     /**//// <summary>
12     ///   Constructor an <see cref="EnumAdapter"/>.
13     /// </summary>
14     /// <param name="value">The enum value.</param>
15     /// <exception cref="">
16     ///   
17     /// </exception>
18     public EnumAdapter(EnumType value)
19     {
20         if (!Enum.IsDefined(typeof(EnumType), value))
21         {
22             throw new ArgumentException(string.Format("{0} is not defined in {1}", value, typeof(EnumType).Name), "value");
23             // It's better use resource version as below.
24             // throw new ArgumentException(SR.GetString("ENUM_NOT_DEFINED_FMT_KEY", value, typeof(EnumType).Name), "value");
25         }
26         _value = value;
27     }
28   
29     /**//// <summary>
30     ///   Gets the actual enum value.
31     /// </summary>
32     public EnumType Value
33     {
34         get { return _value; }
35     }
36   
37     /**//// <summary>
38     ///   Gets the display value for enum value by search local resource with currrent UI lture 
39     ///   and special key which is concated from Enum type name and Enum value name.
40     /// </summary>
41     /// <remarks>
42     ///   This would get correct display value by accessing location resource with current UI Culture.
43     /// </remarks>
44     public string DisplayValue
45     {
46         get { return SR.GetString(string.Format("{0}.{1}", typeof(EnumType).Name, _value.ToString())); }
47     }
48   
49     //TODO: If you want more, please add below
50 }

 

至此,整个功能的框架已经完成,下面我们来看看一些细节——如何对资源读取和管理的封装:

001 /// <summary>
002 ///   Constructor a new <see cref="SR"/>.
003 /// </summary>
004 internal SR()
005 {
006     //TODO: If you modified resource location, please update here
007     this.resources = new System.Resources.ResourceManager(
008         string.Concat(typeof(EnumAdapter).Namespace, ".Resource"), 
009         base.GetType().Assembly);
010 }
011   
012 /**//// <summary>
013 ///   Get singleton instance.
014 /// </summary>
015 /// <returns>A singleton <see cref="SR"/></returns>
016 private static SR GetLoader()
017 {
018     if (loader == null)
019     {
020         lock (SR.InternalSyncObject)
021         {
022             if (loader == null)
023             {
024                 loader = new SR();
025             }
026         }
027     }
028     return loader;
029 }
030   
031 /**//// <summary>
032 ///   Gets an object from resources by special key, which provided by <paramref name="name"/>.
033 /// </summary>
034 /// <param name="name">Resource accessed key</param>
035 /// <returns>return stored object in resource. if resource not found, return <paramref name="name"/> as object.</returns>
036 public static object GetObject(string name)
037 {
038     SR loader = GetLoader();
039     if (loader == null)
040     {
041         return null;
042     }
043     try
044     {
045         return loader.resources.GetObject(name, Culture);
046     }
047     catch { }
048     return name;
049 }
050   
051 /**//// <summary>
052 ///   Gets a string from resources by special key, which provided by <paramref name="name"/>.
053 /// </summary>
054 /// <param name="name">Resource accessed key</param>
055 /// <returns>return stored string in resource. If resource not found, retuen <paramref name="name"/> as result.</returns>
056 public static string GetString(string name)
057 {
058     SR loader = GetLoader();
059     if (loader == null)
060     {
061         return null;
062     }
063     try
064     {
065         return loader.resources.GetString(name, Culture);
066     }
067     catch { }
068     return name;
069 }
070   
071 /**//// <summary>
072 ///   Gets a formatted string from resources by special key, which provided by <paramref name="name"/> and optional parameters.
073 /// </summary>
074 /// <param name="name">Resource accessed key</param>
075 /// <param name="args">format arguments.</param>
076 /// <returns>return stored string in resource. If resource not found, use <paramref name="name"/> as formator, return the formatted string.</retur
077 public static string GetString(string name, params object[] args)
078 {
079     SR loader = GetLoader();
080     if (loader == null)
081     {
082         return null;
083     }
084     string format = name;
085     try
086     {
087         format = loader.resources.GetString(name, Culture);
088     }
089     catch { }
090   
091     if ((args == null) || (args.Length <= 0))
092     {
093         return format;
094     }
095   
096     // It's better cut long arg for formating.
097     for (int i = 0; i < args.Length; i++)
098     {
099         string arg = args[i] as string;
100         if ((arg != null) && (arg.Length > 0x400))
101         {
102             args[i] = arg.Substring(0, 0x3fd) + "";
103         }
104     }
105     return string.Format(System.Globalization.CultureInfo.CurrentCulture, format, args);
106 }

 

OK,大功告成,有了这么一个封装,在应用里就可以简单的这么几句够搞定。

01 private void Form1_Load(object sender, EventArgs e)
02 {
03     this.comboBox1.DataSource = new EnumDataSource<Sex>();
04     this.comboBox1.DisplayMember = "DisplayValue";
05     this.comboBox1.ValueMember = "Value";
06 }
07   
08 public enum Sex
09 {
10     Male,
11     Female
12 }

热推产品

  • ActiveReport... 强大的.NET报表设计、浏览、打印、转换控件,可以同时用于WindowsForms谀坔攀戀Forms平台下......
  • AnyChart AnyChart使你可以创建出绚丽的交互式的Flash和HTML5的图表和仪表控件。可以用于仪表盘的创......
首页 | 新闻中心 | 产品中心 | 技术文档 | 友情连接 | 关于磐岩 | 技术支持中心 | 联系我们 | 帮助中心 Copyright-2006 ComponentCN.com all rights reserved.重庆磐岩科技有限公司(控件中国网) 版权所有 电话:023 - 67870900 传真:023 - 67870270 产品咨询:sales@componentcn.com 渝ICP备12000264号 法律顾问:元炳律师事务所 重庆市江北区塔坪36号维丰创意绿苑A座28-5 邮编:400020
在线客服
在线客服系统
在线客服
在线客服系统