web-dev-qa-db-fra.com

WPF Liaison d'un ListBox à une énumération, affichant l'attribut Description

Est-il possible d'utiliser la méthode ObjectDataProvider pour lier un ListBox à une énumération et lui donner un style pour afficher l'attribut Description? Si oui, comment s'y prendrait-on ...?

33
Michal Ciechan

Oui c'est possible. Cela va le faire. Disons que nous avons l'énum

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

Ensuite, nous pouvons utiliser ObjectDataProvider en tant que

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>

Et pour le contrôle ListBox, nous définissons ItemsSource sur MyEnumValues ​​et appliquons un ItemTemplate avec un convertisseur.

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

Et dans le convertisseur nous obtenons la description et la renvoyons

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

La méthode GetEnumDescription devrait probablement aller ailleurs, mais vous avez l'idée :)

86
Fredrik Hedblad

Si vous vous liez à Enum, vous pourriez probablement convertir cela en description via un IValueConverter.

Voir ComboBox de reliure à des enums ... dans Silverlight! pour une description de la procédure à suivre.

Voir http://msdn.Microsoft.com/en-us/library/system.windows.data.ivalueconverter.aspx pour plus d'informations.

2
Pieter van Ginkel

Vous pouvez définir un fichier de ressource dans votre projet (fichier * .resx). Dans ce fichier, vous devez définir "paires clé-valeur", quelque chose comme ceci:

"YellowCars" : "Yellow Cars",
"RedCars" : "Red Cars",

etc...

Les clés sont égales à vos entrées enum, quelque chose comme ceci:

public enum CarColors
{
    YellowCars,
    RedCars
}

etc...

Lorsque vous utilisez WPF, vous pouvez implémenter dans votre code XAML quelque chose comme ceci:

<ComboBox ItemsSource="{Binding Source={StaticResource CarColors}}" SelectedValue="{Binding CarColor, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Converter={StaticResource CarColorConverter}}" />
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

Ensuite, vous devez écrire votre convertisseur, quelque chose comme ceci:

using System;
using System.Globalization;
using System.Resources;
using System.Windows.Data;

public class CarColorConverter : IValueConverter
{
    private static ResourceManager CarColors = new ResourceManager(typeof(Properties.CarColors));

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var key = ((Enum)value).ToString();
        var result = CarColors.GetString(key);
        if (result == null) {
            result = key;
        }

        return result;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Ma réponse arrive 7 ans trop tard ;-) Mais peut-être que quelqu'un d'autre l'utilisera!

1
peter70