Reputation: 16714
I've lots of enums in my app. Most of them are used on combos like this:
Enum.GetValues(typeof(TipoControlador))
Now I'd like to localize them like this: Localizing enum descriptions attributes
How can I combine them? My first thought was to override the ToString
method with an extension method, but that's not possible =(
Upvotes: 3
Views: 2805
Reputation: 1
I know this question is old, but this may help some people. You can just handle the Format event of the ComboBox control (http://msdn.microsoft.com/en-us/library/system.windows.forms.listcontrol.format.aspx), and add your text logic in it.
private void ComboBoxFormat(object sender, ListControlConvertEventArgs e)
{
e.Value = GetDescription(e.Value);
}
public static string GetDescription(object item)
{
string desc = null;
Type type = item.GetType();
MemberInfo[] memInfo = type.GetMember(item.ToString());
if (memInfo != null && memInfo.Length > 0)
{
object[] attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attrs != null && attrs.Length > 0)
{
desc = (attrs[0] as DescriptionAttribute).Description;
}
}
if (desc == null) // Description not found
{
desc = item.ToString();
}
return desc;
}
With this, the ComboBox control still holds enum values rather than strings.
Upvotes: 0
Reputation: 6479
You have 2 problems here, the first is how to localize enums which is solved by Localizing enum descriptions attributes.
The second is how to display the localized name whilst using the enum's value. This can be solved by creating a simple wrapper object such as:
public sealed class NamedItem
{
private readonly string name;
private readonly object value;
public NamedItem (string name, object value)
{
this.name = name;
this.value = value;
}
public string Name { get { return name; } }
public object Value { get { return value; } }
public override string ToString ()
{
return name;
}
}
This provides a generic re-usable class for any drop down box where you might want to show a different name for an item than the item itself provides (eg enums, ints, etc).
Once you have this class, you can set the drop down's DisplayMember
to Name
and ValueMember
to Value
. This will mean that dropdown.SelectedValue
will still return your enum.
Upvotes: 1
Reputation: 5567
Using the other article as a basis, you can create an extension method like this:
public static class LocalizedEnumExtensions
{
private static ResourceManager _resources = new ResourceManager("MyClass.myResources",
System.Reflection.Assembly.GetExecutingAssembly());
public static IEnumerable<string> GetLocalizedNames(this IEnumerable enumValues)
{
foreach(var e in enumValues)
{
string localizedDescription = _resources.GetString(String.Format("{0}.{1}", e.GetType(), e));
if(String.IsNullOrEmpty(localizedDescription))
{
yield return e.ToString();
}
else
{
yield return localizedDescription;
}
}
}
}
You would use it like this:
Enum.GetValues(typeof(TipoControlador)).GetLocalizedNames();
Technically, this extension method will accept any array, and you can't restrict it to only work on an enum, but you could add extra validation inside the extension method if you feel it's important:
if(!e.GetType().IsEnum) throw new InvalidOperationException(String.Format("{0} is not a valid Enum!", e.GetType()));
Upvotes: 1