Enum localization

后端 未结 15 594
慢半拍i
慢半拍i 2020-11-30 17:56

How do you localize enums for a ListBoxFor where multiple options are possible?

For example an enum that contains roles:

pu         


        
相关标签:
15条回答
  • 2020-11-30 18:17

    I use this currently, hope it helps!:

        /// <summary>
        ///  Retrieves a translated value from an enumerated list.
        /// </summary>
        /// <param name="value">Enum</param>
        /// <param name="resource">string</param>
        /// <returns>string</returns>
        protected string GetTranslatedEnum(Enum value, string resource)
        {
            string path = String.Format("Resources.{0}", resource);
    
            ResourceManager resources = new ResourceManager(path, global::System.Reflection.Assembly.Load("App_GlobalResources"));
    
            if (resources != null) {
                return resources.GetString(value.ToString());
            } else {
                return value.ToString();
            }
        }
    

    Created a .resx file named "App_GlobalResources\ProductNames.resx".

    Usage:

    // Convert the ProductId integer on the item to its Enum equivalent.
    Products product = (Products) item.ProductId;
    
    string productName = this.GetTranslatedEnum(product, "ProductNames");
    
    0 讨论(0)
  • 2020-11-30 18:22

    You could use Lexical.Localization¹ which allows embedding default value and culture specific values into the code, and be expanded in external localization files (like .json, .resx or .ini) for futher cultures.

    namespace Library
    {
        enum Permissions
        {
            Create = 1,
            Drop = 2,
            Modify = 4,
            GrantCreate = 8,
            GrantDrop = 16,
            GrantModify = 32
        }
    }
    

    In Program code:

    // Load localization.ini
    LineRoot.Builder.AddLocalizationFile("localization.ini").Build();
    // Create key for enum
    ILine key = LineRoot.Global.Assembly("ConsoleApp4").Type<Permissions>().Format("{0}");
    // Print 
    Console.WriteLine(key.Value(Permissions.Create | Permissions.Drop));
    Console.WriteLine(key.Value(Permissions.Create | Permissions.Drop).Culture("en"));
    Console.WriteLine(key.Value(Permissions.Create | Permissions.Drop).Culture("fi"));
    

    localization.ini:

    [Assembly:ConsoleApp4:Type:Library.Permissions:Culture:fi]
    Key:Create = Luonti
    Key:Drop = Poisto
    Key:Modify = Muutos
    Key:GrantCreate = Luonnin myöntö
    Key:GrantDrop = Poiston myöntö
    Key:GrantModify = Muutoksen myöntö
    
    [Assembly:ConsoleApp4:Type:Library.Permissions:Culture:en]
    Key:Create = Create
    Key:Drop = Drop
    Key:Modify = Modify
    Key:GrantCreate = Grant Create
    Key:GrantDrop = Grant Drop
    Key:GrantModify = Grant Modify 
    

    ¹ (I'm maintainer of that library)

    0 讨论(0)
  • 2020-11-30 18:23

    There is a way of using attributes to specify a string to use for enums when displaying them, but we found it way too fiddly when you had to handle localization.

    So what we usually do for enums that need to be localized is to write an extension class that provides a method to obtain the translated name. You can just use a switch that returns strings from the usual resources. That way, you provide translated strings for enums via the resources just like you do for other strings.

    For example:

    public enum Role
    {
        Administrator,
        Moderator,
        Webmaster,
        Guest
    }
    
    public static class RoleExt
    {
        public static string AsDisplayString(this Role role)
        {
            switch (role)
            {
                case Role.Administrator: return Resources.RoleAdministrator;
                case Role.Moderator:     return Resources.RoleModerator;
                case Role.Webmaster:     return Resources.RoleWebmaster;
                case Role.Guest:         return Resources.RoleGuest;
    
                default: throw new ArgumentOutOfRangeException("role");
            }
        }
    }
    

    Which you can use like this:

    var role = Role.Administrator;
    Console.WriteLine(role.AsDisplayString());
    

    If you keep the RoleExt class implementation next to the enum Role implementation it will effectively become part of the interface for Role. Of course you could also add to this class any other useful extensions for the enum .

    [EDIT]

    If you want to handle multiple flags settings ("Administrator AND Moderator AND Webmaster") then you need to do things a little differently:

    [Flags]
    public enum Roles
    {
        None          = 0,
        Administrator = 1,
        Moderator     = 2,
        Webmaster     = 4,
        Guest         = 8
    }
    
    public static class RolesExt
    {
        public static string AsDisplayString(this Roles roles)
        {
            if (roles == 0)
                return Resources.RoleNone;
    
            var result = new StringBuilder();
    
            if ((roles & Roles.Administrator) != 0)
                result.Append(Resources.RoleAdministrator + " ");
    
            if ((roles & Roles.Moderator) != 0)
                result.Append(Resources.RoleModerator + " ");
    
            if ((roles & Roles.Webmaster) != 0)
                result.Append(Resources.RoleWebmaster + " ");
    
            if ((roles & Roles.Guest) != 0)
                result.Append(Resources.RoleGuest + " ");
    
            return result.ToString().TrimEnd();
        }
    }
    

    Which you might use like this:

    Roles roles = Roles.Administrator | Roles.Guest | Roles.Moderator;
    Console.WriteLine(roles.AsDisplayString());
    

    Resource Files

    Resource files are the way that you internationalize your strings. For more information on how to use them, see here:

    http://msdn.microsoft.com/en-us/library/vstudio/aa992030%28v=vs.100%29.aspx http://msdn.microsoft.com/en-us/library/vstudio/756hydy4%28v=vs.100%29.aspx

    0 讨论(0)
提交回复
热议问题