WPF: Simple way to use enums as ComboBox items

A lot of times in GUIs we use ComboBoxes to let the user choose one of several options. An enum property is a natural fit to store the selected value in the viewmodel via databinding.

To set the available values the MVVM way you typically have to databind the ItemsSource-Property to a collection. This means you have to code a collection somewhere, either in your viewmodel or in a static class. For Example:

  class SomeViewModel
  {
      public ContactType[] PossibleContactTypes => new ContactType[] { 
          ContactType.Email,
          ContactType.Sms,
          ContactType.Phone 
      };

      public ContactType SelectedContactType { get; set; }
  }

And then use one way binding to set PossibleContactTypes as ItemsSource:

<ComboBox ItemsSource="{Binding PossibleContactTypes}"
          SelectedItem="{Binding SelectedContactType}" />

If you have a lot of enum backed ComboBoxes this adds a lot of extra lines of code to your viewmodels.

But: If our goal is to display all values in the enum, we can create a collection containing all of them from just the enum type. Plus we can create a custom markup extension to get rid of the boilerplate code in our viewmodels. The markup extension looks like this:

    public class EnumCollectionExtension : MarkupExtension
    {
        public Type EnumType { get; set; }

        public override object ProvideValue(IServiceProvider _)
        {
            if(EnumType != null)
            {
                return CreateEnumValueList(EnumType);
            }
            return default(object);
        }

        private List<object> CreateEnumValueList(Type enumType)
        {
            return Enum.GetNames(enumType)
                .Select(name => Enum.Parse(enumType, name))
                .ToList();
        }
    }

Now we can use it to set our ComboBox items like this:

<ComboBox ItemsSource="{e:EnumCollection EnumType=model:ContactType}"
          SelectedItem="{Binding SelectedContactType}" />

The drawback with this approach is that it only works if we want to use all values of an enum on the Control.

Hope this is helpful!

Leave a Reply

Your email address will not be published. Required fields are marked *