I know this is an old question, but for some reason it is rather complicated, although it seems that this will be a fairly common task (currently I am doing this in a UWP application). Using a combination of the accepted answer, some other elements that I found, and a bit of my own work, here is the easiest way I found to complete this difficult task. In short:
- Define your list along with setting a description in the Display attribute
- Create a converter that converts from an enumeration value to a description
- In your view model, output a collection of enumeration values ββfrom which to select the selected enumeration value, then initialize these
- Identify some convenient ways to extend enum
- Finally, some simple binding to the ComboBox, just overriding its ItemTemplate to use the converter.
Enum
public enum EnumOptions { [Display(Description = "Option 1")] OptionOne= 1, [Display(Description = "Option 2")] OptionTwo, [Display(Description = "Option 3")] OptionThree }
Converter
public class EnumToDisplayConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) { var enumValue = value as Enum; return enumValue == null ? DependencyProperty.UnsetValue : enumValue.GetDescriptionFromEnumValue(); } public object ConvertBack(object value, Type targetType, object parameter, string language) { return value; } }
Viewmodel (partial)
public IReadOnlyList<EnumOptions> Options { get; } private EnumOptions _selectedOption; public EnumOptions SelectedOption { get { return _selectedOption; } set { _selectedOption = value; OnPropertyChanged(() => SelectedOption); } } // Initialization in constructor Options = EnumExtensions.GetValues<EnumOptions>().ToArray(); // If you want to set a default. SelectedOption = Options[0];
Extensions
public static class EnumExtensions { public static string GetDescriptionFromEnumValue(this Enum value) { var attribute = value.GetType() .GetField(value.ToString()) .GetCustomAttributes(typeof(DisplayAttribute), false) .SingleOrDefault() as DisplayAttribute; return attribute == null ? value.ToString() : attribute.Description; } /// <summary> /// Enumerates all enum values /// </summary> /// <typeparam name="T">Enum type</typeparam> /// <returns>IEnumerable containing all enum values</returns> /// <see cref="http://stackoverflow.com/questions/972307/can-you-loop-through-all-enum-values"/> public static IEnumerable<T> GetValues<T>() { return Enum.GetValues(typeof (T)).Cast<T>(); } }
XAML (partial)
<TextBlock Grid.Row="1">Choose an option</TextBlock> <ComboBox Grid.Row="2" ItemsSource="{Binding Options}" SelectedItem="{Binding SelectedOption, Mode=TwoWay}"> <ComboBox.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding Converter={StaticResource EnumToDisplayConverter}}"></TextBlock> </DataTemplate> </ComboBox.ItemTemplate> </ComboBox>
Joe
source share