Vishful thinking…

Databinding Enum values to combo boxes

Posted in .NET, C#, DataBinding by viswaug on June 13, 2007

Even though I dislike the use of enumerations, there are cases where you can use them to make your life a lot easier. In those cases, there might be a requirement to have the enumeration property data bound to a combo box which lists all possible values of the enumeration in some meaningful text and also be able to select the right enumeration text when the object is bound to it. I have written a small little utility that will do just that. It returns a Read-Only collection with some meaningful text as the “Name” and the enum value as the “Value” member of the collection. In the sample, the generic class EnumCollection<T> has a static DataSource property that returns a ReadOnlyICollection that is data bindable to a combo box. The type T represents an enumeration type. The text to describe the enumeration values can be added as custom attribute decorators in the definition of the enumeration as below.

 

1 public enum EnumSample

2 {

3 [Text(“This is One.”)]

4 One,

5 [Text(“This is Two.”)]

6 Two,

7 [Text(“This is Three.”)]

8 Three,

9 [Text(“This is Four.”)]

10 Four

11 }

 

The EnumCollection<T> class creates its collection in a static constructor for the generic class and thus is able to return the required collection in a static “DataSource” property. The definition of the EnumCollection<T> class is below.

 

1 public class EnumCollection<T> : ReadOnlyCollection<EnumClass<T>>

2 {

3 static EnumCollection<T> _val;

4

5 static EnumCollection()

6 {

7 if (!typeof(T).IsEnum)

8 throw new InvalidCastException(“sbEnumCollection only supports ‘enum’ types.”);

9

10 List<EnumClass<T>> vals = new List<EnumClass<T>>();

11 Array values = Enum.GetValues(typeof(T));

12 foreach (Object item in values)

13 {

14 EnumClass<T> entry = new EnumClass<T>(GetText<T>(item), (T)item);

15 vals.Add(entry);

16 }

17 _val = new EnumCollection<T>(vals);

18 }

19

20 private static string GetText<U>(object item) where U : T

21 {

22 if (!typeof(U).IsEnum)

23 throw new InvalidCastException(“GetText only supports ‘enum’ types.”);

24

25 FieldInfo fi = typeof(U).GetField(item.ToString());

26 string result = null;

27 if (fi != null)

28 {

29 object[] attrs = fi.GetCustomAttributes(typeof(TextAttribute), true);

30 if (attrs != null && attrs.Length > 0)

31 result = ((TextAttribute)attrs[0]).Text;

32 }

33

34 if (result == null)

35 result = Enum.GetName(typeof(T), item);

36

37 return result;

38 }

39

40 internal EnumCollection(IList<EnumClass<T>> list) : base(list) { }

41

42 public static EnumCollection<T> DataSource

43 {

44 get

45 {

46 return _val;

47 }

48 }

49 }

 

Enumerations can be data bound to combo boxes easily as shown below.

 

 

1 comboBox1.DataSource = EnumCollection<EnumSample>.DataSource;

2 comboBox1.DisplayMember = “Name”;

3 comboBox1.ValueMember = “Value”;

 

The complete project can be downloaded here.