为了账号安全,请及时绑定邮箱和手机立即绑定

枚举的多语言显示

标签:
资讯

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

 

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

 

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

 

?

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

 

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

 

?


/// <summary>///   Enum value adapter, used to get values from each Cultures./// </summary>public sealed class EnumAdapter{    /**//// <summary>    ///   Storage the actual Enum value.    /// </summary>    private EnumType _value;     /**//// <summary>    ///   Constructor an <see cref="EnumAdapter"/>.    /// </summary>    /// <param name="value">The enum value.</param>    /// <exception cref="">    ///       /// </exception>    public EnumAdapter(EnumType value)    {        if (!Enum.IsDefined(typeof(EnumType), value))        {            throw new ArgumentException(string.Format("{0} is not defined in {1}", value, typeof(EnumType).Name), "value");            // It's better use resource version as below.            // throw new ArgumentException(SR.GetString("ENUM_NOT_DEFINED_FMT_KEY", value, typeof(EnumType).Name), "value");        }        _value = value;    }     /**//// <summary>    ///   Gets the actual enum value.    /// </summary>    public EnumType Value    {        get { return _value; }    }     /**//// <summary>    ///   Gets the display value for enum value by search local resource with currrent UI lture     ///   and special key which is concated from Enum type name and Enum value name.    /// </summary>    /// <remarks>    ///   This would get correct display value by accessing location resource with current UI Culture.    /// </remarks>    public string DisplayValue    {        get { return SR.GetString(string.Format("{0}.{1}", typeof(EnumType).Name, _value.ToString())); }    }     //TODO: If you want more, please add below}

 

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

 

?


/// <summary>///   Constructor a new <see cref="SR"/>./// </summary>internal SR(){    //TODO: If you modified resource location, please update here    this.resources = new System.Resources.ResourceManager(        string.Concat(typeof(EnumAdapter).Namespace, ".Resource"),         base.GetType().Assembly);} /**//// <summary>///   Get singleton instance./// </summary>/// <returns>A singleton <see cref="SR"/></returns>private static SR GetLoader(){    if (loader == null)    {        lock (SR.InternalSyncObject)        {            if (loader == null)            {                loader = new SR();            }        }    }    return loader;} /**//// <summary>///   Gets an object from resources by special key, which provided by <paramref name="name"/>./// </summary>/// <param name="name">Resource accessed key</param>/// <returns>return stored object in resource. if resource not found, return <paramref name="name"/> as object.</returns>public static object GetObject(string name){    SR loader = GetLoader();    if (loader == null)    {        return null;    }    try    {        return loader.resources.GetObject(name, Culture);    }    catch { }    return name;} /**//// <summary>///   Gets a string from resources by special key, which provided by <paramref name="name"/>./// </summary>/// <param name="name">Resource accessed key</param>/// <returns>return stored string in resource. If resource not found, retuen <paramref name="name"/> as result.</returns>public static string GetString(string name){    SR loader = GetLoader();    if (loader == null)    {        return null;    }    try    {        return loader.resources.GetString(name, Culture);    }    catch { }    return name;} /**//// <summary>///   Gets a formatted string from resources by special key, which provided by <paramref name="name"/> and optional parameters./// </summary>/// <param name="name">Resource accessed key</param>/// <param name="args">format arguments.</param>/// <returns>return stored string in resource. If resource not found, use <paramref name="name"/> as formator, return the formatted string.</returpublic static string GetString(string name, params object[] args){    SR loader = GetLoader();    if (loader == null)    {        return null;    }    string format = name;    try    {        format = loader.resources.GetString(name, Culture);    }    catch { }     if ((args == null) || (args.Length <= 0))    {        return format;    }     // It's better cut long arg for formating.    for (int i = 0; i < args.Length; i++)    {        string arg = args[i] as string;        if ((arg != null) && (arg.Length > 0x400))        {            args[i] = arg.Substring(0, 0x3fd) + "";        }    }    return string.Format(System.Globalization.CultureInfo.CurrentCulture, format, args);}

 

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

 

?


private void Form1_Load(object sender, EventArgs e){    this.comboBox1.DataSource = new EnumDataSource<Sex>();    this.comboBox1.DisplayMember = "DisplayValue";    this.comboBox1.ValueMember = "Value";} public enum Sex{    Male,    Female}
点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消