Converter to show enumeration description and convert back to enum value when selecting an item from a combo box in wpf

I use enum to enlist values ​​in my list. I want to write a converter that will show a "description" of the selected enumeration value. And, if selected, it will return the value of the enumeration.

Most converters on the Internet have not implemented the ConvertBack () method (which is why I post here).

Thanks in advance.

+11
enums c # converter wpf
source share
5 answers

Here is the 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> 
+16
source share

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> 
+4
source share
 [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 } 
+2
source share

Addition to the above examples to show decoration of an enumeration with attributes.

 sealed class DescriptionAttribute : Attribute { readonly string description; public DescriptionAttribute(string description) { this.description = description; } public string Description { get { return description; } } } enum Vehicle { [Description("Benz")] Car, [Description("Volvo")] Bus, [Description("Honda")] Bike } 

By the way, I wonder why you needed to convert the description to enum. If you provide the enumerations themselves as an ItemSource, you can use the description method to display the displayed value in the ComboBox, however, once an item is selected, you can directly have an enumeration as the selected item.

0
source share

Here is my working example:

Enum definition:

 public enum MyEnum { [Description("Exchange 2007")] E2007, [Description("Exchange 2010")] E2010, [Description("Exchange 2013")] E2013, }; 

Helper Class:

 public static class cHelperClass { #region GetValuesAndDescriptions public static object[] GetValuesAndDescriptions(Type enumType) { var kvPairList = new List<KeyValuePair<string, string>>(); var listValue = Enum.GetValues(enumType); for (var i = 0; i < listValue.Length; i++) { var value = listValue.GetValue(i); var enumValue = (Enum)listValue.GetValue(i); kvPairList.Add(new KeyValuePair<string, string>(value.ToString(), GetDescription(enumValue))); } var valuesAndDescriptions = from kv in kvPairList select new { Value = kv.Key, Description = kv.Value }; return valuesAndDescriptions.ToArray(); } public static string GetDescription(this Enum value) { var fieldInfo = value.GetType().GetField(value.ToString()); var attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false); return (attributes.Length > 0) ? attributes[0].Description : value.ToString(); } public static string GetStringValue(this Enum enumItem) { return enumItem .GetType() .GetField(enumItem.ToString()) .GetCustomAttributes<StringValueAttribute>() .Select(a => a.Value) .FirstOrDefault() ?? enumItem.ToString(); } public static string GetName(Type enumType, object value) { return Enum.GetName(enumType, value); } #endregion } 

XAML:

 <UserControl.Resources> <!-- ObjectDataProvider fΓΌr WindowStyles --> <ObjectDataProvider x:Key="myEnumResource" MethodName="GetValuesAndDescriptions" ObjectType="classes:cHelperClass"> <ObjectDataProvider.MethodParameters> <x:Type TypeName="classes:MyEnum" /> </ObjectDataProvider.MethodParameters> </ObjectDataProvider> </UserControl.Resources> <ComboBox ItemsSource="{Binding Source={StaticResource myEnumResource}}" DisplayMemberPath="Description" SelectedValuePath="Value" SelectedValue="{Binding MyEnum, Mode=TwoWay}" /> 
0
source share

All Articles