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 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>
[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
}