Converter to show description of an enum, and convert back to enum value on selecting an item from combo box in wpf
Here is ConvertBack method:
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture){ return value;}
Full Converter Code:
public class EnumConverter : IValueConverter{ public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if (value == null) return DependencyProperty.UnsetValue; return GetDescription((Enum)value); } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { return value; } public static string GetDescription(Enum en) { Type type = en.GetType(); MemberInfo[] memInfo = type.GetMember(en.ToString()); if (memInfo != null && memInfo.Length > 0) { object[] attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false); if (attrs != null && attrs.Length > 0) { return ((DescriptionAttribute)attrs[0]).Description; } } return en.ToString(); }}
EDIT
Here is my ComboBox XAML:
<ComboBox ItemsSource="{Binding SampleValues}" SelectedItem="{Binding SelectedValue, Converter={StaticResource enumConverter}}"> <ComboBox.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding Path=., Converter={StaticResource enumConverter}}" /> </DataTemplate> </ComboBox.ItemTemplate></ComboBox>
I know this is an old question, but for some reason, this is rather complicated, even though it seems like it'd be a pretty common task (I'm currently doing this on a UWP app). Using a combination of the accepted answer, some other items I found, and a bit of my own work, here's the simplest way I've found to accomplish this menial task. In short:
- Define your enum along w/ setting the description in the Display attribute
- Create a converter that converts from an enum value to the description
- In your viewmodel, expose a collection of enum values from which to choose, the selected enum value, then initialize those
- Define a couple of handy enum extension methods
- 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 constructorOptions = 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>
[ValueConversion(typeof(MyEnum), typeof(String))]public class MyEnumConverter : IValueConverter{ public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { var enumVal = (MyEnum)value; // in this example, this is an extension method return enumValue.Description(); } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { var enumDesc = value as string; MyEnum val; if (Enum.TryParse(typeof(MyEnum), strValue, out val)) { return val; } return DependencyProperty.UnsetValue; }}
The extension method in the example might look like this:
public static string Description(this MyEnum enumVal){ // you could use a switch statement here; // or maybe a Dictionary}