Brendan Tompkins [MVP]

Sponsors

The Lounge

News

Advertisement

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
Strongly Type DropDownList with .NET Attributes!

A while back I posted about using an enum as a datasource for your drop-down lists, see Strongly-Type a DropDownList with Enumerated Types.  As it turns out, the big drawback to this approach is that your DropDownList's text is limited to the text that you use in your enum.  This is fine if your text doesn't have any spaces, or other special characters, since enumerations don't allow these.  But most of the time, you'll need a more presentable version of your text to show to your end-users. 

One approach would be to create a method to convert your enumerated value to text, switching on the value.  This isn't the best approach, however, because you've now logically separated the original enum from it's text representation, which can lead to some problems with maintenance.  Also the code for doing this can get ugly, and really should probably be relegated to The Daily WTF

Fortunately, there's a better way: Attributes.  I've been reading Applied .NET Attributes, by Jason Bock and Tom Barnaby recently, and attributes are a perfect solution to this problem.  They keep the meaning of the enum together with the definition, and the code to access this information is simple and straight forward.   So, here's the code from the last post, re-written to use attributes:

The new enumeration, with the Description attribute:

public enum TShirtSize
{
      [Description("Small (size 0-5)")] Small =
0,
      [Description("Medium (size 6-10)")] Medium =
1,
      [Description("Large (size 10-13)")] Large =
2,
      [Description("Extra-Large (sizes 13 and up)")] ExtraLarge =
3
}

A helper method to reflect and get the Description:

public static string GetDescription(Enum value)
{
  FieldInfo fi= value.GetType().GetField(value.ToString());
  DescriptionAttribute[] attributes =

     (DescriptionAttribute[])fi.
GetCustomAttributes(typeof(DescriptionAttribute), false);
  return (attributes.
Length>0) ? attributes[0].Description : value.ToString();
}

And finally, our new ddl code:

DropDownList ddl = new DropDownList();
foreach(TShirtSize siz in Enum.GetValues(typeof
(TShirtSize)))
{
   
ddl.Items.Add(
      new ListItem(GetDescription(siz), Convert.ToInt32(siz).ToString())
    );
}

For more on this, see this great article, Mapping Text to Enum entries By Reto Ravasio

-Brendan


Posted 12-08-2004 7:07 AM by Brendan Tompkins

[Advertisement]

Comments

icodemarine@gmail.com (Tim Weaver) wrote RE: Strongly Type DropDownList with .NET Attributes!
on 12-08-2004 3:30 AM
Very cool.
Since there is a fair amount of reflection going on here I would suggest you add some caching either to the GetDescription method or simply cache the entire ddl.
Brenton House wrote re: Strongly Type DropDownList with .NET Attributes!
on 12-08-2004 5:13 AM
We found building translator classes to convert from enum to string was necessary as we defining our enum on the service side of a web service and using it on the client side. It loses the attributes when going through the web service. If anyone has a better suggestion, please let me know!
Brendan Tompkins wrote re: Strongly Type DropDownList with .NET Attributes!
on 12-08-2004 5:18 AM
Hmmm. Yes, I can see this being a problem. At the least, your translator class could just be a wrapper to the GetDescrition() method on the server, right?
Dave Donaldson wrote re: Strongly Type DropDownList with .NET Attributes!
on 12-08-2004 11:11 AM
Nice. Thanks.
Mihir Solanki wrote re: Strongly Type DropDownList with .NET Attributes!
on 12-08-2004 8:48 PM
cool !!!
Noam wrote re: Strongly Type DropDownList with .NET Attributes!
on 11-28-2008 5:28 AM

This is a nice solution, but how does it work with internationalization?

Brendan Tompkins wrote re: Strongly Type DropDownList with .NET Attributes!
on 12-01-2008 8:34 AM

Noam: Yes, it doesn't.  

Add a Comment

(required)  
(optional)
(required)  
Remember Me?