Using RIA Services with ComboBoxes and Enums

The other day someone asked me how to get a ComboBox working with enums and validation. It turned out to be more tricky than I had anticipated (there’s a common theme here…) so I figured I’d put together a quick post on it.

Stumbling Points

This section describes two specific traps I fell into. It’s not necessarily important for you to understand the details, but I’ll include them just in case you’re interested. Feel free to skip straight to the solution.

My first error was related to sharing enums in RIA. Due to the way enums appear in assembly metadata, the RIA code generator can’t determine whether they exist on the client or not. If you put an enum in a .shared.cs or .shared.vb file, it will quickly result in a compile error. The solution to this issue is simple. Instead of sharing the enum between tiers, just define it on your server and let codegen take care of the rest.

The second error I ran into was using client-side projection properties. In the past I’ve preferred these to using an IValueConverter in my bindings, but this investigation (finally) helped me to realize this approach has adverse effects on RIA validation. When the property being validated is named something other than the property being set (for example, the MyString property would write through to the MyEnum property where validation would occur) the visual control state will not be updated to reflect the error (no fancy red adornment).

The Solution

I eventually ended up using an IValueConverter-based solution. I put a little extra work into it to make it DisplayAttribute-aware since metadata is a commonly-used RIA feature. I wrote a utility to encapsulate most of this, but I’ll go over that piece at the end once you’ve got a grip on how it all fits together. (Similar variants of this solution are available in a number of places, but I wanted to fill in some of the corners that often get ignored)

I applied these changes to the sample I used in this post ( if you want a place to try it out. These steps should work in any scenario, though.


To create the look above, I defined a simple enum with DisplayAttributes on each of the values.

  public enum MyEnum
    [Display(Name = "(please pick a value)")]
    None = 0,
    [Display(Name = "Value 1")]
    Value1 = 1,
    [Display(Name = "Value 2")]
    Value2 = 2,
    [Display(Name = "Value 3")]
    Value3 = 3,

Then I added a property to my entity that used custom validation to ensure a non-zero value is selected.

  [CustomValidation(typeof(Validation), "ValidateMyEnum")]
  public MyEnum MyEnum { get; set; }

(My validation is in a shared file in the web project, Validation.shared.cs)

  public static class Validation
    public static ValidationResult ValidateMyEnum(
MyEnum myEnum, ValidationContext context) { if (myEnum == MyEnum.None) { return new ValidationResult(
"You must pick a value.", new[] { context.MemberName }); } return ValidationResult.Success; } }

My next step was to define the ComboBox on the client.

  <ComboBox ItemsSource="{StaticResource myEnumNames}"
            SelectedItem="{Binding Path=MyEnum,
Converter={StaticResource enumToString}}"

The SelectedItem binding references a converter I instantiate in my page resources.

  <app:EnumToStringValueConverter x:Key="enumToString" />

The code for the converter is simple and leverages the EnumUtility I’ll describe a little later. It is also generic so a single instance can be shared between multiple types of enums.

  public class EnumToStringValueConverter : IValueConverter
    public object Convert(object value, Type targetType,
object parameter, CultureInfo culture) { return EnumUtility.GetName(value.GetType(), value); } public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture) { return EnumUtility.GetValue(targetType, value.ToString()); } }

The ItemsSource in the ComboBox above uses a static resource I add in my page constructor before parsing the xaml (in InitializeComponent). I’ve used the EnumUtility again to get the names for my enum.

  this.Resources.Add("myEnumNames", EnumUtility.GetNames(typeof(MyEnum)));

With all the pieces in place (an enum, a property to bind to, a converter, a list of names, and a ComboBox), I now have a ComboBox bound to an enum and validating input.

An Enum Utility

I wrote a utility class to handle most of the heavy lifting here. For each enum type, it iterates through all the values and figures out the names they should be mapped to. The GetName and GetValue methods map back and forth between the two. Here’s the source in case you’re interested.

  public static class EnumUtility
    private static readonly
IDictionary<Type, IEnumerable<string>> names =
new Dictionary<Type, IEnumerable<string>>(); private static readonly
IDictionary<Type, IEnumerable<object>> values =
new Dictionary<Type, IEnumerable<object>>(); private static readonly
IDictionary<Type, IDictionary<string, object>> namesToValues =
new Dictionary<Type, IDictionary<string, object>>(); private static readonly
IDictionary<Type, IDictionary<object, string>> valuesToNames =
new Dictionary<Type, IDictionary<object, string>>(); public static void Initialize(Type type) { Initialize(type, GetDisplayAttributeName); } public static void Initialize(
Type type, Func<FieldInfo, string> getName) { if (type == null) { throw new ArgumentNullException("type"); } if (!type.IsEnum) { throw new ArgumentException("Type must be an enum.", "type"); } if (getName == null) { throw new ArgumentNullException("getName"); } if (names.ContainsKey(type)) { return; } List<string> tempNames = new List<string>(); List<object> tempValues = new List<object>(); Dictionary<string, object> tempNamesToValues =
new Dictionary<string, object>(); Dictionary<object, string> tempValuesToNames =
new Dictionary<object, string>(); foreach (FieldInfo fi in
type.GetFields(BindingFlags.Public | BindingFlags.Static)) { string name = getName(fi); object value = fi.GetValue(null); tempNames.Add(name); tempValues.Add(value); tempNamesToValues[name] = value; tempValuesToNames[value] = name; } names[type] = tempNames; values[type] = tempValues; namesToValues[type] = tempNamesToValues; valuesToNames[type] = tempValuesToNames; } private static string GetDisplayAttributeName(FieldInfo fi) { DisplayAttribute displayAttribute =
typeof(DisplayAttribute), false).FirstOrDefault(); return (displayAttribute == null) ? fi.Name : displayAttribute.Name; } public static IEnumerable<string> GetNames(Type type) { Initialize(type); return names[type]; } public static IEnumerable<object> GetValues(Type type) { Initialize(type); return values[type]; } public static string GetName(Type type, object value) { Initialize(type); return valuesToNames[type][value]; } public static object GetValue(Type type, string name) { Initialize(type); return namesToValues[type][name]; } }
Comments (8)

  1. H2Ocoder says:

    Kyle, thanks for posting this information.  Most real world scenarios will use ComboBoxes to restrict data entry.  It would also be very valuable to have a post, video, or tutorial on how to fill a ComboBox from a database lookup table, which is a very common business app scenario.  I have found various posts on this but all seemed to dead end in failure.  It seems that the major errors are how to bind the ComboBox with the lookup table, and to have the proper item in the ComboBox selected upon navigation to it.

    Any help with this would be greatly appreciated!



  2. kylemc says:


    It doesn't explicitly address pulling from a lookup table, but the sample from this post uses a list of values provided by the server (take a look at the 'A' ComboBoxes). All you need to do is follow the same pattern and return results from your lookup table.…/combobox-sample-for-ria-services.aspx

  3. SBark says:

    Kyle, great post.  Appreciate your work on these.  I'm working on a SL4 RIA project, back-end Azure Table Storage.  I need to put a drop down list (combo box) in MainPage.xaml to change the Hyperlink text.  The drop down will have a selection of languages (English, Spanish, etc) and when a user picks one, the text changes.  Do I need to adjust the code you have posted here for any post-back issues for it residing in MainPage.xaml?  The text of the hyperlinks is bound to something like Content="{Binding Path=ApplicationStrings.HomePageTitle  but I believe I need to bound it to a string dictionary or something along those lines then use INotifableCollectionChange to update the text…right?

    Thanks again.

  4. H2Ocoder says:

    So if I understand correctly, in my SL4 RIA Business App solution, I need to include the ComboBoxExtensions project and follow this post and the post on the A Comboboxes.  I will give that a try.

    Thanks again for the help.

  5. kylemc says:


    Hmm… a localization question. I'm not sure what others are doing, but you might consider recreating the page. I haven't seen any solutions using INotifyPropertyChanged for application resources. It doesn't mean it isn't possible, I'm just not sure how much work it would be. If you re-navigate or re-create the page the bindings will re-read the resources.

  6. SBark says:

    Thanks Kyle.  My thought would be the drop down list would be in the "header", not the body of the MainPage.xaml…if that helps to shed some light on my situation.  At least in pseudo code, I can see the text of the hyperlinks bound to some "binding path", then when the combo box in the header changes, the "converter" logic in some method updates the text.  Appreciate it.  

  7. Peter Wone says:

    Localisation: perhaps locale might be specified as a value converter parameter?

  8. kylemc says:


    I assumed you could implement localization using existing patterns for the DisplayAttribute and CustomValidationAttribute. Is there a reason you'd want to do it a different way?

Skip to main content