Bind an Enum

25 באוגוסט 2008

תגיות: ,
7 תגובות

It's very useful to take an enum and bind it into bind-able controls (like drop down list, check box, grid view and etc). For example, if we have an enum which represents bug statuses and you want to bind it into a drop down list.

public enum Bug
{
Opened = 1,
Closed = 2,
Rejected = 3,
Resolved = 4,
InProgress = 5
}

In addition, usually in a UI we want to separate between the enum words (for example to change the "InProgress" to "In Progress").

I search over the net and I found some solution but in all of them I needed to extend my current enum (like using attribute in this solution), so I decided to implement one of myself:

public static class EnumHelper
{
public static IDictionary<string, int> GetList<TEnum>()
{
return GetList<TEnum>(false);
}

public static IDictionary<string, int> GetList<TEnum>(bool splitString)
{
Type type = typeof(TEnum);
Dictionary<string, int> list = new Dictionary<string, int>();
Array enumValues = Enum.GetValues(type);
foreach (Enum value in enumValues)
{
int enumValue = Convert.ToInt32(((TEnum)Enum.Parse(type, value.ToString())));
string sb = (splitString) ? SplitString(value) : value.ToString();
list.Add(sb, enumValue);
}
return list;
}

private static string SplitString(Enum value)
{
StringBuilder sb = new StringBuilder();
char[] chars = value.ToString().ToCharArray();

sb.Append(chars[0]);
for (int i = 1; i < chars.Length – 1; i++)
{
if ((chars[i].ToString() == chars[i].ToString().ToUpper())
&& (chars[i - 1].ToString() != chars[i - 1].ToString().ToUpper()))
{
sb.Append(" ");
}
sb.Append(chars[i]);
}
sb.Append(chars[chars.Length - 1]);
return sb.ToString();
}
}


How do we use this code?

In case we just want to bind it without separate between the enum words, it will be like this:

var bugs = EnumHelper.GetList<Bug>();

And in case we want to separate between the words will have something like that:

var bugs = EnumHelper.GetList<Bug>(true);

Challenge:

How do you synchronies between enum (which execute in web/service context) and a table/database context?

For example you have this bug statuses enum and in addition you have a bug table with numeric status column. The status column values are the same enum numeric values. After deployment, in order to understand this column value you must look at the enum that represent it. But in order to do so, you must open your code…

הוסף תגובה
facebook linkedin twitter email

כתיבת תגובה

האימייל לא יוצג באתר. (*) שדות חובה מסומנים

7 תגובות

  1. Shani Raba25 באוגוסט 2008 ב 17:28

    Hey Wortzel,
    How you doing?
    anyway, I think that you might create a _static_ table. The table will hold the enum values and description.

    and the main table will hold a number from that table (foreign key)

    anyway, you can easily generate the enum from this table.

    Enjoy.

    להגיב
  2. Avi Wortzel27 באוגוסט 2008 ב 16:09

    Hi Shani,
    It's good to hear from you :)
    It's a good idea, maybe it'll be better to create the enum in the source code and then to insert it into this static table when the system will be loaded.
    10x,
    Avi

    להגיב
  3. Jim8 באוקטובר 2008 ב 9:41

    I frequently come across this kind of thing in codebases I have to maintain, and it annoys the hell out of me :-)

    Why don't you use a proper class to represent your "Bug" (which should really be a "BugStatus" or something) and have that class do the formatting for you? That's what object oriented languages are for.

    Jim

    להגיב
  4. Avi Wortzel26 באוקטובר 2008 ב 2:15

    Hi Jim,
    You are right, I should call this enum BugStatus, and I'll have another class which will represent the bug entity.
    But still in order to bind all bug statuses I'll need to use this BugStatus enum.
    10x

    להגיב
  5. David Lay17 בדצמבר 2008 ב 15:02

    Avi, Great blog, glad to have found it!

    I often find myself using enums in the code to represent status and type tables of the database.

    Often we use them as master tables, referred by one or many data tables.

    I have a helper method similar to yours, but I actually call the database for descriptions (doing some caching of course) of the numbers (I have a rather useful custom DAL that figures everything based on the enum name), so we get the best of both worlds, and if the program finds a mismatch between the enum and table, it throws a exception that the software catch and inform gently to myself that something is not right (usually the change is in the database, so this tells me that i forgot to update my enum)

    להגיב
  6. delm17 בדצמבר 2008 ב 15:08

    oh, and using classes to encapsulate type and status tables … been there, done that.
    It's a overkill.. all that boilerplate code … We only need numbers with names right?
    the problem is throw them to a stupid (yeah, stupid and old) combobox, and I've found the enum to IDictionary is the way to go. just a workaround to make the combobox happy and display the number names in a beautifully way.

    להגיב
  7. Avi Wortzel6 במרץ 2009 ב 7:59

    Hi Deml,
    I don't disagree with you, enums gives you to work with strongly types in you code. I really think it can reduce some bugs in your system…
    Avi

    להגיב