Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF How to bind an enum with Description to a ComboBox

How can I bind an enum with Description (DescriptionAttribute) to a ComboBox?

I got an enum:

public enum ReportTemplate
{
    [Description("Top view")]
    TopView,

    [Description("Section view")]
    SectionView
}

I tried this:

<ObjectDataProvider MethodName="GetValues" ObjectType="{x:Type System:Enum}"
                    x:Key="ReportTemplateEnum">
    <ObjectDataProvider.MethodParameters>
        <x:Type TypeName="Helpers:ReportTemplate"/>
    </ObjectDataProvider.MethodParameters>
</ObjectDataProvider>

<Style x:Key="ReportTemplateCombobox" TargetType="dxe:ComboBoxEditSettings">
    <Setter Property="ItemsSource" 
            Value="{Binding Source={x:Type Helpers:ReportTemplate}}"/>
    <Setter Property="DisplayMember" Value="Description"/>
    <Setter Property="ValueMember" Value="Value"/>
</Style>

Can't succeed to do this, any simple solution?

Thanks in advance!

like image 707
dg90 Avatar asked Mar 22 '13 10:03

dg90


People also ask

How do I change the ComboBox style in WPF?

In visual studio, open WPF designer, select combo box control, then right click combo box control and select Edit template, then select Edit a Copy. This will create a style template, you can modify it as you need.

How do I add a ComboBox item in WPF?

On button click event handler, we add the content of TextBox to the ComboBox by calling ComboBox. Items. Add method. Now if you enter text in the TextBox and click Add Item button, it will add contents of the TextBox to the ComboBox.


2 Answers

This can be done by using a converter and item template for your comboBox.

Here is the converter code which when bound to an enum will return the Description value:

namespace FirmwareUpdate.UI.WPF.Common.Converters
{
    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;
        }
    }
}

Then in your xaml you need to use and item template.

<ComboBox Grid.Row="1" Grid.Column="1"  Height="25" Width="100" Margin="5"
              ItemsSource="{Binding Path=MyEnums}"
              SelectedItem="{Binding Path=MySelectedItem}"
              >
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Converter={StaticResource enumDescriptionConverter}}"/>
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>
like image 133
RSmaller Avatar answered Oct 31 '22 18:10

RSmaller


RSmaller has a good answer, and is the one I use as well, with one caveat. If you have more than one attribute on your enums, and Description isn't the first listed then his "GetEnumDescription" method will throw an exception...

Here is a slightly safer version:

    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 = null;

            foreach( var att in attribArray)
            {
                if (att is DescriptionAttribute)
                    attrib = att as DescriptionAttribute;
            }

            if (attrib != null )
                return attrib.Description;

            return enumObj.ToString();
        }
    }
like image 5
Brock Avatar answered Oct 31 '22 16:10

Brock