Enums are great for fixed lists of options, including things like user configurable application options. But what do you do in cases like this with the UI? You could just hard code it, which sounds fine, enums are hard coded too. However this isn't so fine when you need to add another value later; You have to go back and adjust the UI, and if you have lots of screens which display the same options there is always the chance you will miss one.
Wouldn't it be nice to get a list of values for an enum, with some display text included that you could bind to UI control, or iterate over to create things like radio buttons dynamically? You could just write some code to parse each enum and give you what you want, but that's a bit tedious too. What you really want is to be able to attach display text to the enum values right where they are defined and have a common function to get a list for you. And that's exactly what you get here:
How To Use It
Reference EnumUtil.dll in your project and EnumUtil in your namespace. Add an EnumDisplayText attribute to each item in your enum. The first parameter takes the text you want to display and the second takes an integer which defines the display order. Items with the same display order will be grouped and sorted alphabetically by display text. If an item does not have an attribute it will get the item name as its display text and 0 as its display order.
public enum DemoEnum
{
[EnumDisplayText("Hello,", 0)]
a,
[EnumDisplayText("This is", 1)]
b,
[EnumDisplayText("a lovely", 2)]
c,
[EnumDisplayText("list.", 3)]
d
}
To get a list containing the enum items with their display text use the static method GetList() from the generic class Enums<T>, where T is the enum you want.
List<EnumListItem<DemoEnum>> enumList = Enums<DemoEnum>.GetList();
You'll get back a generic list of type EnumListItem. The EnumListItem has the following fields:
- EnumValue – An item from your enum
- Name – The name of the item
- DisplayText – The display text you specified in the item attribute
- DisplayOrder – The display order you specified in the item attribute
So, for example, to bind the list to a winforms list box you could do this:
List<EnumListItem<DemoEnum>> enumList = Enums<DemoEnum>.GetList();
this.listBox1.DisplayMember = "DisplayText";
this.listBox1.ValueMember = "EnumValue";
this.listBox1.DataSource = enumList;
If you just want to get the display text for a specific enum item use GetDisplayText(T item).
string displayText = Enums<DemoEnum>.GetDisplayText(DemoEnum.a);
There is a little demo application included with the source that shows all this stuff in use.
How It Works
I'll walk through the GetDisplayText method, GetList does the same thing in a loop..
public static string GetDisplayText(Enum item)
{
Type type = item.GetType();
MemberInfo[] memberInfo = type.GetMember(item.ToString());
if (memberInfo != null && memberInfo.Length > 0)
{
object[] customAttributes = memberInfo[0].GetCustomAttributes(typeof(EnumDisplayText), false);
if (customAttributes != null && customAttributes.Length > 0)
{
return ((EnumDisplayText)customAttributes[0]).DisplayText;
}
}
return item.ToString();
}
First up, we get the type of the enum, then we query the type to get the details of the enum item we are interested in. Next, we get the custom attributes for the item (only attributes of type EnumDisplayText). If we find an attribute of the right type, access the DisplayText field and return it, otherwise return the name of the item.
That's it!
Thanks to Abhinaba Basu for his blog post which inspired this / did all the hard work..
Enjoy!