Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
Show User-Friendly enum Translations

It's common to populate a drop-down box with enum values or, similarly, to display an enum setting to the user.  The problem is that enum values usually aren't very pretty to look at.  (Memories of hoping QA wouldn't spot "OrderShipped" come to mind.)  In a previous post by Joe Niland, Joe suggested that attributes be used to maintain the user-friendly version of enum values.  What follows is a solution for doing just that.

What we need is a class that will satisfy the following unit-test:

[TestFixture] public class EnumDescriptionTests { [Test] public void CanRetrieveEnumTextAndDescription() { // Simply uses the enum value itself as the text representation by default Assert.That( EnumDescription.TextRepresentation.GetTextRepresentationOf(OrderStatus.Delivered), Is.EqualTo("Delivered")); Assert.That( EnumDescription.TextRepresentation.GetDescriptionOf(OrderStatus.Delivered), Is.EqualTo(String.Empty)); Assert.That( EnumDescription.TextRepresentation.GetTextRepresentationOf(OrderStatus.InventoryDepleted), Is.EqualTo("Out of Stock")); Assert.That( EnumDescription.TextRepresentation.GetDescriptionOf(OrderStatus.InventoryDepleted), Is.EqualTo(String.Empty)); Assert.That( EnumDescription.TextRepresentation.GetTextRepresentationOf(OrderStatus.InventoryComing), Is.EqualTo("More in Stock Soon")); Assert.That( EnumDescription.TextRepresentation.GetDescriptionOf(OrderStatus.InventoryComing), Is.EqualTo("An order for more items has been placed with the supplier")); } private enum OrderStatus { Delivered, [EnumDescription.TextRepresentation("Out of Stock")] InventoryDepleted, [EnumDescription.TextRepresentation("More in Stock Soon", "An order for more items has been placed with the supplier")] InventoryComing } }

When a description is provided for an enum value, via the "Description" attribute, then the provided description is returned.  When a description isn't available, the ToString version of the enum value, with spaces put before each capital letter, is returned, instead. 

So then to satisfy the unit test:

public class EnumDescription { public class TextRepresentationAttribute : Attribute { public readonly string Text; public readonly string Description = ""; public TextRepresentationAttribute(string text) { Text = text; Description = ""; } public TextRepresentationAttribute(string text, string description) { Text = text; Description = description; } } public class TextRepresentation { public static string GetTextRepresentationOf(Enum enumType) { TextRepresentationAttribute textRepresentation = GetTextRepresentationAttributeFor(enumType); return textRepresentation != null ? textRepresentation.Text : enumType.ToString(); } public static string GetDescriptionOf(Enum enumType) { TextRepresentationAttribute textRepresentation = GetTextRepresentationAttributeFor(enumType); return textRepresentation != null ? textRepresentation.Description : String.Empty; } private static TextRepresentationAttribute GetTextRepresentationAttributeFor(Enum enumType) { MemberInfo[] memberInfo = enumType.GetType().GetMember(enumType.ToString()); if (memberInfo != null && memberInfo.Length == 1) { object[] customAttributes = memberInfo[0].GetCustomAttributes(typeof(TextRepresentationAttribute), false); if (customAttributes.Length == 1) { return (TextRepresentationAttribute) customAttributes[0]; } } return null; } } }

This should make a useful addition to any utility library.

Billy


Posted 10-16-2006 2:39 PM by Billy McCafferty
Filed under: ,

[Advertisement]

Comments

Derik Whittaker wrote re: Show User-Friendly enum Translations
on 10-16-2006 7:00 PM

Bill,

Great post.  I have used code like this in the past to build combo boxes.  Gotta love the power of reflection.

Dave Donaldson wrote re: Show User-Friendly enum Translations
on 10-16-2006 10:51 PM

Yet another excellent use of attributes. I'm giving an attributes talk in a couple weeks. Mind if I use this as an example?

Billy McCafferty wrote re: Show User-Friendly enum Translations
on 10-17-2006 12:46 AM

Don't mind at all...mi coda su coda.  Just be sure to mention devlicio.us! ;)

Rob Herbert wrote re: Show User-Friendly enum Translations
on 10-17-2006 3:18 AM

I've used something similar, but instead of holding the actual description in the attribute value, I hold a Resource key so that the descriptions can be localised. It can add a lot of work, but then writing properly localised code always does. :-(

Rob Eisenberg wrote re: Show User-Friendly enum Translations
on 10-17-2006 7:45 AM

I like the custom attribute idea.  Let me suggest an alternate default behavior.  If there is no attribute supplied, why not ToString the enum and insert a space before each capital letter (except the first)?  This will allow a "pretty print" of enums over which you don't have source and perhaps lessen the number attributes you have to apply.

Billy McCafferty wrote re: Show User-Friendly enum Translations
on 10-17-2006 7:54 AM

Great suggestion...now if only I could get a handle on RegEx to figure out how to do that cleanly! ;)

Rob Herbert wrote re: Show User-Friendly enum Translations
on 10-17-2006 8:53 AM

I'm sure there's a way to do this without the Trim, but here's a quick stab at a suitable RegEx:

string s = "ThisIsATest";

Regex t = new Regex( "[A-Z]", RegexOptions.Compiled );

string u = t.Replace( s, " $&" ).Trim();

Console.WriteLine( u );

Rob Herbert wrote re: Show User-Friendly enum Translations
on 10-17-2006 9:56 AM

I forgot about the \B assertion. This'll do the job.

string s = "ThisIsATest";

string t = new Regex( "\\B[A-Z]", RegexOptions.Compiled ).Replace(s, " $&");

Console.WriteLine( t );

Sean wrote re: Show User-Friendly enum Translations
on 10-17-2006 12:16 PM

Great post.  I took advantage of the regex comment and extended it to include some optional details  that we'll use for reflected "help" for a given enumType.

Thanks for the idea!

lb wrote re: Show User-Friendly enum Translations
on 10-19-2006 1:46 AM

nice.

i wrote a bad regex for this a while back. seems to do the job. (linked in my name)

Tom Opgenorth wrote re: Show User-Friendly enum Translations
on 11-15-2006 11:36 AM

I've done something exactly like this a couple of times on past projects.  Works great.

The next exercise in this problem is one of localization:  "Order shipped" probably looks different German or Spanish. I was thinking that the GetDescriptionOf() method could maybe look up the description from a satellite assembly if necessary.

Billy McCafferty wrote re: Show User-Friendly enum Translations
on 11-16-2006 11:21 AM

I (un)fortunately have not had to worry about localization much with my project work.  It has therefore put me in the comfortably, pompous position - within my code anyway - that everyone knows English fluently and has US-culture, regional settings! ;)  But I shot myself in the foot with this during my refactoring challenge after people from around the world were getting varying results from DateTime.Parse("2/1/06")...I continue to learn something new everyday!

Adi wrote re: Show User-Friendly enum Translations
on 11-19-2006 12:59 PM

You can also use the System.ComponentModel.DescriptionAttribute instead of creating yours. Great post.

Rodel E. Dagumampan wrote re: Show User-Friendly enum Translations
on 11-24-2006 6:55 PM

One of the issues of using this is that list displayed on comboxes and list controls cannot be localized or I may have just missed how to do it. So i just created tables for lookup on this records for databinding list controls, but i also have enums. It goes like this,

databse table:

Shipping(IdShipping, IdLocale, Shipping)

class:

ShippingEN {IdShipping, IdLocale, Shipping}

enum:

enum ShippingENU {

 NextDay

 2Days,

 3Days,

 etcs..

}

//commit

Order  order = new Order();

order.IdShipping = (int)dropDownList.SelectedValue;

//bll

if(order.IdShipping == (int)ShippingENU.NextDay){

 if(order.TotalWithTax == 200){

  //do something here

 }

}

Shipping sample is just a sample so you may find this hard to maintain ;). But my point is we cannot use the reflection strategry  here.

HTH. Visit my blog if you have time ;)

:: filipino developer

Mark Erikson wrote re: Show User-Friendly enum Translations
on 01-28-2007 2:08 PM

Just thought I'd toss in a couple of useful additions.  First, to change this to use the built-in DescriptionAttribute class, change the GetCustomAttributes call to use typeof(DescriptionAttribute) and change the next section to:

enumDescription = ((DescriptionAttribute)customAttributes[0]).Description;

Also, here's a companion function that will return an enum given the description and the type:

public static Enum GetEnumFromDescription(string description, Type enumType)

{

Hashtable ht = new Hashtable();

Enum result = null;

foreach (Enum e in Enum.GetValues(enumType))

{

string enumDescription = GetDescriptionOf(e);

if(description.Equals(enumDescription))

{

result = e;

break;

}

}

return result;

}

Naz wrote re: Show User-Friendly enum Translations
on 06-03-2008 12:45 PM

There's an alternative way of doing this using extension methods.

www.objectreference.net/.../enum-to-friendly-string-extension-method.aspx

This method required you to defined the extension method for all enum types.

Billy McCafferty wrote re: Show User-Friendly enum Translations
on 06-03-2008 12:57 PM

Hi Naz,

Thanks for the tip.  My only concern with the approach you've suggested is that if the enum listing changes, you have to change it in two places.  But again, always nice to see alternative approaches!

devlicio.us wrote re: Show User-Friendly enum Translations
on 06-04-2011 8:06 PM

Show User_2D00_Friendly enum Translations.. I like it :)

7w4r sex videos aqn0 wrote re: Show User-Friendly enum Translations
on 07-02-2011 1:50 AM

Show User_2D00_Friendly enum Translations.. Awful :)

egmdbbex wrote re: Show User-Friendly enum Translations
on 02-29-2012 1:47 AM

uglifdin

Social bookmarks wrote re: Show User-Friendly enum Translations
on 03-23-2013 5:49 AM

K5bxOA Really informative article post.Much thanks again. Will read on...

social bookmarking service wrote re: Show User-Friendly enum Translations
on 03-23-2013 1:57 PM

AZHHGX Fantastic article.Really looking forward to read more. Cool.

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Subscribe
Google Reader or Homepage

del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of Devlicio.us
Red-Gate Tools For SQL and .NET

NDepend

SlickEdit
 
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
Unfuddle
Balsamiq Mockups
Scrumy
JetBrains - ReSharper
Umbraco
NServiceBus
RavenDb
Web Sequence Diagrams
Ducksboard<-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)