Converter to show description of an enum, and convert back to enum value on selecting an item from combo box in wpf Converter to show description of an enum, and convert back to enum value on selecting an item from combo box in wpf wpf wpf

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}