Blog from Saravanan Arumugam

Let us talk about Technologies

User friendly name for Enumeration fields


Unlike class’s properties, showing user friendly display name for an enumeration field is not that easy.

For example, I would like to use the following Enum. But when I display them on screen, I want to display “Prior Record” instead of “PriorRecord”, and “Future Record” instead of “FutureRecord”.

public enum RecordStatus
{
   New = 0,

   Error = 1,

   PriorRecord = 2,

   FutureRecord = 4,

   ExcessHours = 8,
}

I tried to use DisplayNameAttribute, but its not applicable to Enums and Fields. So I had to do something equivalent to it.

1. Create Custom Attribute to specify friendly names

First thing to do is to create a custom attribute which I can use to specify the Display Name of each field. We can take advantage of DisplayNameAttribute by deriving the custom type from it. DisplayNameAttribute has all infrastructure already specified. We just need to create a class with constructors.

[AttributeUsage(AttributeTargets.Field)]
public class EnumDisplayNameAttribute : DisplayNameAttribute
{
    public EnumDisplayNameAttribute()
        : base()
    {
 
    }
 
    public EnumDisplayNameAttribute(string displayName)
        : base(displayName)
    {
 
    }
}

Note that I have placed an AttributeUsageAttribute to make this attribute available for fields.

 

2. Use the custom attribute on the Enum fields

Next thing to do is to use the attribute to specify the friendly name.

[Flags]
public enum RecordStatus
{
	New = 0,
 
	Error = 1,
 
	[EnumDisplayName("Prior Record")]
	PriorRecord = 2,
 
	[EnumDisplayName("Future Record")]
	FutureRecord = 4,
 
	[EnumDisplayName("Excess Hours")]
	ExcessHours = 8,
}

 

3. Write an extension method to Enum

Next thing is to show the DisplayName whenever Enum.ToString() is called. We have to write an overload to the ToString() as an extension.

public static class EnumExtension
{
/// <summary>
/// Shows the user friendly name specified in EnumDisplayNameAttribute
/// </summary>
/// <param name="enumeration">Enumeration object</param>
/// <param name="indicator">An indicator to enable this extension. 
/// Pass any integer as indicator.</param>
/// <returns>User friendly name of the Enumeration</returns>
public static string ToString(this Enum enumeration, bool indicator)
{
    string returnValue = enumeration.ToString();
 
    if (indicator)
    {
        //Flagged enumeration will have comma separated value.
        //Split them into multiple values before use.
        var displayValues =
           //Split is made here to handle all the comma separated enum values
            from enumValue in enumeration.ToString().Split(',')
            //Join is made here to work with field object instead of string.
            join field in enumeration.GetType().GetFields()
            on enumValue.Trim() equals field.Name
            select field
                into enumFields
                //If the field has the EnumDisplayAttribute, display it;
                //otherwise, display the regular field name.
                //Conditional output is done through the ternary operator.
                select
                (enumFields.GetCustomAttributes(false).Any(attribute =>
                    attribute is EnumDisplayNameAttribute) ?
                (from attribute in enumFields.GetCustomAttributes(false)
                    where attribute is EnumDisplayNameAttribute
                    select ((EnumDisplayNameAttribute)attribute).DisplayName)
                    .First()
                : enumFields.Name);
 
        if (displayValues.Count() > 0)
            returnValue = string.Join(", ", displayValues);
    }
    return returnValue;
}
}

Note that the ToString() method contains a Boolean indicator. If it is true, the ToString() would return the friendly names else will return the defaults.

The linq statement in the method has 3 levels of loops.

Loop 1. Since the enum is marked with FlagAttribute, the default ToString() may produce comma separated values such as Error, ExcessHours, FutureRecord. So in the linq we split them into an array of strings.

Loop 2. Find the FieldInfo object based on the string we received from the previous loop.

Loop 3. If the field has EnumDisplayNameAttribute, return the DisplayName. If the field doesn’t have the custom attribute, return the FieldInfo.Name.

 

4. Use the overloaded ToString() method

Now in the places where we need the friendly name, start using the ToString(true).

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine(
            (RecordStatus.Error 
            | RecordStatus.ExcessHours).ToString(true));
        Console.WriteLine(
            RecordStatus.ExcessHours 
            | RecordStatus.FutureRecord);
    }
}

image

Advertisements

3 responses to “User friendly name for Enumeration fields

  1. online mobile shopping websites April 25, 2012 at 10:00 pm

    This publication has inspired me to continue working on my own blog

  2. shshs April 28, 2012 at 7:35 pm

    You have remarked very interesting details! ps decent internet site.

  3. nootropic April 29, 2012 at 3:51 pm

    Hello, i think that i noticed you visited my web site thus i came to “go back the favor”.I am trying to find issues to enhance my website!I assume its adequate to make use of some of your ideas!!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: