WPF Привязка ListBox к перечислению с отображением атрибута описания - PullRequest
34 голосов
/ 21 октября 2010

Можно ли использовать метод ObjectDataProvider для привязки ListBox к перечислению и стилизовать его каким-либо образом для отображения атрибута Description? Если так, то как можно поступить так ...?

Ответы [ 3 ]

88 голосов
/ 21 октября 2010

Да, это возможно.Это сделает это.Скажем, у нас есть enum

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

Затем мы можем использовать ObjectDataProvider в качестве

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>

И для ListBox мы устанавливаем ItemsSource в MyEnumValues ​​и применяем ItemTemplate с конвертером..

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

И в конвертере мы получаем описание и возвращаем его

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

Метод GetEnumDescription, вероятно, должен идти куда-то еще, но вы понимаете:)

2 голосов
/ 21 октября 2010

Если вы привязываетесь к Enum, вы, вероятно, можете преобразовать это в описание через IValueConverter.

См. Связывание ComboBox с перечислениями ... в Silverlight! для описания того, какдля этого.

См. http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.aspx для получения дополнительной информации.

1 голос
/ 12 ноября 2017

Вы можете определить файл ресурсов в вашем проекте (файл * .resx). В этом файле вы должны определить «пары ключ-значение», что-то вроде этого:

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

и так далее ...

Ключи равны вашим перечислениям, что-то вроде этого:

public enum CarColors
{
    YellowCars,
    RedCars
}

и так далее ...

Когда вы используете WPF, вы можете реализовать в своем XAML-коде что-то вроде этого:

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

Тогда вы должны написать свой конвертер, что-то вроде этого:

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

Мой ответ опаздывает на 7 лет ;-) Но, может быть, его может использовать кто-то еще!

...