Click here to Skip to main content
Click here to Skip to main content

Description Enum TypeConverter

, 3 Mar 2004
Rate this:
Please Sign up or sign in to vote.
This article explains how to manage to make a TypeConverter for enums using its descriptions.

Click to Enlarge

Click Image to Enlarge

Introduction

I had been looking everywhere about information on TypeConverters, specially their uses for the PropertyGrid. There's not much documentation about it, and I kinda needed it for some work stuff. That said, I'm presenting you here a simple EnumConverter which allows the use of the DescriptionAttribute to convert from and to the Enum values. This is great for presentation on a PropertyGrid, as you don't want either your Enum names appearing all over an application, neither you.

Background

I was in the process of creating a 3D engine in C#, and I was making tools to edit materials and a lot of more stuff. Each material, texture, etc, can have tons of properties, and I was aiming to discover a way of making my UI fast and with no mistakes. The usual way (making labels and textboxes/comboboxes/whatever) would be just too time-consuming, and I was (am) on a tight schedule. So I came across the PropertyGrid.

As the C# newbie I am, I started fiddling around the System.ComponentModel attributes to make my classes browsable on a PropertyGrid, so I first made 'Editable' wrappers which I'd only use on the tools (no need to overload the engine with things I won't use afterwards). This is a partial IBitmap editable class, so you know what I'm talking about:

namespace Immerse.Editables
{
  [DefaultProperty("Name")]
  public class EditableIBitmap
  {
    private IBitmap bmp;
    
    public EditableIBitmap(IBitmap bmp) 
    {
      this.bmp = bmp;
    }

    [Browsable(false)]
    public IBitmap Bitmap { get { return bmp; } } 

    [Browsable(true), 
      DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
    [Category("Bitmap Properties"),Description("Bitmap Name")]
    [DefaultValue("Unnamed Bitmap")]
    public string Name { get { return bmp.Name; } }
    [Category("Bitmap Properties"),Description("Bitmap Width")]
    public int    Width { get { return bmp.Width; } }
    [Category("Bitmap Properties"),Description("Bitmap Height")]
    public int    Height { get { return bmp.Height; } }
    [Category("Bitmap Properties"),Description("Bitmap Depth")]
    public int    Depth { get { return bmp.Depth; } }
    [Category("Bitmap Properties"),Description("Bits per Pixel")]
    public int    Bpp { get { return bmp.Bpp; } }
    [Category("Bitmap Properties"),Description("Number of Dimensions (1-3)")]
    public int    Dimensions { get { return bmp.Dimensions; } }

    [Category("Bitmap Properties"),Description("Texture Tiling U")]
    public TextureTileTypes TileTypeU 
    { get { if(bmp.TileType.Length > 0) 
               return bmp.TileType[0]; 
            else return TextureTileTypes.Tile; } }
    [Category("Bitmap Properties"),Description("Texture Tiling V")]
    public TextureTileTypes TileTypeV 
    { get { if(bmp.TileType.Length > 1) 
                return bmp.TileType[1]; 
            else return TextureTileTypes.Tile; } }
    [Category("Bitmap Properties"),Description("Texture Tiling W")]
    public TextureTileTypes TileTypeW 
    { get { if(bmp.TileType.Length > 2) 
                return bmp.TileType[2]; 
            else return TextureTileTypes.Tile; } }
  }
}

So, this is not complete, but might give you a nice idea about how I got my editable wrappers implemented. Now, when put on a PropertyGrid, I'd get all the values. There's no setters put on this example, but you get the idea (I don't have them implemented like this, this is just an example).

So I made my own ColorPicker converter and some more stuff. Everything was working great, since it came the time of 'touching up' so it'd have a nice look, and was actually usable for other people than me. The main problem came with all different Enums I had on the program.

For example, TextureTileTypes, is an Enum like:

  public enum TextureTileTypes
  {
    Tile,
    Clmp,
    ClmpB,
    ClmpE,
  }

So in the PropertyGrid, my values would look like 'Tile','Clmp','ClmpB','ClmpE'. Not pretty much user-friendly, uh?

Trying to find some documentation in the net, everyone suggested that I should make a "TextureTileTypeConverter" and roll my own values... that's fine for one Enum, but not quite right for the tons of Enums I have spread all over my engine on possibly editable properties.

So, using the System.ComponentModel.DescriptionAttribute, I got to do this:

  public enum TextureTileTypes
  {
    [Description("Tile")]            Tile,
    [Description("Clamp")]           Clmp,
    [Description("Clamp to Border")] ClmpB,
    [Description("Clamp To Edge")]   ClmpE,
  }

They're, much easier to edit, much easier to code, and definitely no hassle to get a human-readable description of it. Now I just needed a way for the PropertyGrid to display the Description names, while still retaining the normal enum values for the setters. And that converter is what I'm presenting to you now.

Using the code

The code should be self-explanatory for anyone who has ever done any kind of custom TypeConverter for a PropertyGrid. You just set the ConverterAttribute of your editable class to typeof(EnumDescConverter), and that should do the trick.

Notice the following function:

    public static string GetEnumDescription(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();
    }

That should return the human-readable description set to the Enum value, if it has any, if it doesn't, then it just returns the Name as if you had done a ToString().

The other way around:

    public static string GetEnumName(System.Type value, string description)
    {
      FieldInfo [] fis = value.GetFields();
      foreach(FieldInfo fi in fis) 
      {
        DescriptionAttribute [] attributes = 
          (DescriptionAttribute[])fi.GetCustomAttributes
          (typeof(DescriptionAttribute), false);
        if(attributes.Length>0) 
        {
          if(attributes[0].Description == description)
          {
            return fi.Name;
          }
        }
      }
      return description;
    }

So you can use those separately to retrieve any human-readable-form enum value, anywhere in your code. That should be useful enough by itself.

About (the juicy stuff), using the TypeConverter, just include the source file (EnumDescConverter.cs) somewhere in your project, and for your editable class (or however you want the browsing to be done), add typeof(Jcl.Util.EnumDescConverter), like this:

    [System.ComponentModel.TypeConverter(typeof(Jcl.Util.EnumDescConverter))]
    public MyEnumType MyProperty 
    { get { return myEnumVariable; } set { myEnumVariable = value; } }

Of course, you are 100% allowed to change the namespace and put it on your own Smile | :)

Points of Interest

There are pretty much unbearable bugs appearing up when you start writing TypeConverters (as well as extending any other part of the .NET Framework), and most of them are very hard to find, as the documentation is not specially good yet, and there is no source for the .NET Framework, so there are many things going on the background which you can't just trace, as they are event-driven in the application. Once you get the rid of it though it's pretty easy to catch up.

License

You can use the code for free, you may include it in your applications, and you might modify it. Basically, do whatever you want with it. If you get to use it in your application, make sure you notify me about it, and credit would be appreciated, while not required.

History

First version of this document on 25th Feb 2004. Will try to make an example project soon.

Contact

You may contact me for anything related to this article at jcl at vmslabs dot com.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

Share

About the Author

Javier Campos
Web Developer
Spain Spain
I work at Sellmaster Software, S.L., as a software developer and graphic designer.
I've been programming since 1994 and done projects in x86 Assembler, C, C++, Delphi and lately C#.

Comments and Discussions

 
GeneralOnline Tool for EnumTypeConverter PinmemberDuke Voldemar18-Mar-11 9:30 
GeneralWithout discriptions [modified] PinmemberNegative20118-Aug-09 20:12 
GeneralThanks!! Pinmemberwhg14430-Apr-09 9:40 
GeneralPropertyGrid problem Pinmemberinyoface_ca13-Jun-07 10:36 
GeneralRe: PropertyGrid problem PinmemberJavier Campos13-Jun-07 12:04 
GeneralRe: PropertyGrid problem PinmemberLaubi26-Jul-07 21:36 
QuestionASP.NET PinmemberMember #274622614-Jan-07 22:06 
QuestionDotNet 2.0 Enhancement? PinmemberBernd Wißler12-Dec-06 22:13 
GeneralRe: DotNet 2.0 Enhancement? Pinmemberyxjie223-May-11 21:12 
GeneralNot working with DataGrid ComboBox Pinmemberjimbutler10116-Nov-06 0:48 
AnswerRe: Not working with DataGrid ComboBox PinmemberBernd Wißler12-Dec-06 22:16 
GeneralAnother Enhancement PinmemberThis is retarted26-Apr-06 0:24 
GeneralEnhancement Pinmembermickyddoyle16-Mar-06 3:34 
GeneralRe: Enhancement PinmemberJavier Campos16-Mar-06 4:03 
GeneralVB not works! Pinsusscarloqueirolo3-Oct-05 21:47 
GeneralRe: VB not works! PinmemberJavier Campos16-Mar-06 4:04 
GeneralEnum.ToString Method PinmemberAli Demirkaya15-Sep-05 3:38 
GeneralRe: Enum.ToString Method PinmemberJavier Campos15-Sep-05 11:48 
GeneralQuestion about object names. PinmemberDon Riesbeck14-Sep-05 7:06 
GeneralRe: Question about object names. PinmemberJavier Campos14-Sep-05 7:22 
GeneralRe: Question about object names. PinmemberDon Riesbeck14-Sep-05 7:47 
GeneralRe: Question about object names. PinmemberMichalBebas21-Jun-06 23:40 
GeneralRe: Object (Property) names - solution PinmemberBobbie Boy27-Oct-05 9:09 
GeneralPlease update your source here PinmemberJohn Cardinal7-Apr-05 6:47 
GeneralRe: Please update your source here PinmemberJavier Campos7-Apr-05 6:49 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140821.2 | Last Updated 4 Mar 2004
Article Copyright 2004 by Javier Campos
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid