Search code examples
c#wpfdata-bindingenumslistbox

WPF Binding a ListBox to an enum, displaying the Description Attribute


Is it possible to use the ObjectDataProvider method to bind a ListBox to an enum, and style it somehow to display the Description attriibute? If so how would one go about doing this...?


Solution

  • Yes, it is possible. This will do it. Say we have the enum

    public enum MyEnum
    {
        [Description("MyEnum1 Description")]
        MyEnum1,
        [Description("MyEnum2 Description")]
        MyEnum2,
        [Description("MyEnum3 Description")]
        MyEnum3
    }
    

    Then we can use the ObjectDataProvider as

    xmlns:MyEnumerations="clr-namespace:MyEnumerations"
    
    <ObjectDataProvider MethodName="GetValues"
                    ObjectType="{x:Type sys:Enum}"
                    x:Key="MyEnumValues">
        <ObjectDataProvider.MethodParameters>
            <x:Type TypeName="MyEnumerations:MyEnum" />
        </ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>
    

    And for the ListBox we set the ItemsSource to MyEnumValues and apply an ItemTemplate with a Converter.

    <ListBox Name="c_myListBox" SelectedIndex="0" Margin="8"
            ItemsSource="{Binding Source={StaticResource MyEnumValues}}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Converter={StaticResource EnumDescriptionConverter}}"/>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    

    And in the converter we get the description and return it

    public class EnumDescriptionConverter : IValueConverter
    {
        private string GetEnumDescription(Enum enumObj)
        {
            FieldInfo fieldInfo = enumObj.GetType().GetField(enumObj.ToString());
    
            object[] attribArray = fieldInfo.GetCustomAttributes(false);
    
            if (attribArray.Length == 0)
            {
                return enumObj.ToString();
            }
            else
            {
                DescriptionAttribute attrib = attribArray[0] as DescriptionAttribute;
                return attrib.Description;
            }
        }
    
        object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            Enum myEnum = (Enum)value;
            string description = GetEnumDescription(myEnum);
            return description;
        }
    
        object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            return string.Empty;
        }
    }
    

    The GetEnumDescription method should probably go somewhere else but you get the idea :)

    Check GetEnumDescription as extension method.