WPF拉枚举说明(如果可用于填充ComboBox)

时间:2018-10-02 18:15:35

标签: wpf

我有一个枚举,其中某些项设置了DescriptionAttribute。

我想在我的WPF应用程序中有一个下拉菜单,用户可以从该列表中选择一个项目,但是我希望该下拉菜单使用Description值(如果可用)。

我编写了代码以获取值列表(如果可用,则删除描述,否则请使用名称),并且我拥有要用于对象提供程序的XAML,但是它没有填充任何内容。

如果我将GetValues与ObjectType Definition一起使用,则XAML可以工作。

C#

        public static string[] GetDescriptions(Enum enumType)
    {
        List<string> descriptions = new List<string>();

        Type t = enumType.GetType();
        foreach(string name in Enum.GetNames(t))
        {
            FieldInfo field = t.GetField(name);
            object[] d = field.GetCustomAttributes(typeof(DescriptionAttribute), true);
            if (d.Any())
            {
                descriptions.Add(((DescriptionAttribute)d[0]).Description);
            }
            else
            {
                descriptions.Add(name);
            }
        }

        return descriptions.ToArray();
    }

XAML:

        <ObjectDataProvider x:Key="SkillEnum" MethodName="KwCommon:EnumExtensions.GetDescriptions" >
        <ObjectDataProvider.MethodParameters>
            <x:Type TypeName="local:SkillLevels"/>
        </ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>

1 个答案:

答案 0 :(得分:0)

我做类似的事情将枚举绑定到组合框。我有几个辅助函数:

    public static string GetEnumDescription<TEnum>(this TEnum value)
    {
        FieldInfo fi = value.GetType().GetField(value.ToString());

        DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);

        if (attributes != null && attributes.Length > 0)
        {
            return attributes[0].Description;
        }
        else
        {
            return value.ToString();
        }
    }

此函数将枚举转换为键值对列表:

    public static IEnumerable<KeyValuePair<string, Enum>> GetEnumList(this Enum t, bool useDescription = true)
    {
        return Enum.GetValues(t.GetType()).Cast<Enum>().Select(e => new KeyValuePair<string, Enum>(useDescription == true ? e.GetEnumDescription() : e.ToString(), e)).ToList();
    }

我创建了一个转换器(在我的情况下是markupextension,这是该markupextension的链接)

public class EnumToListConverter : ConverterMarkupExtension<EnumToListConverter>
{
    public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        bool useDescription = true;
        if (parameter is bool p)
        {
            useDescription = p;
        }
        if (value is Enum e)
        {
            return EnumHelper.GetEnumList(e, useDescription);
        }

        return DependencyProperty.UnsetValue;
    }

    public override object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return DependencyProperty.UnsetValue;
    }
}

然后在我的xaml中,我像这样使用它:

<ComboBox Grid.Column="1" Grid.Row="1" ItemsSource="{Binding Applicant.RentOrOwn, Converter={local:EnumToListConverter}, Mode=OneTime}" SelectedValuePath="Value" DisplayMemberPath="Key" SelectedValue="{Binding Applicant.RentOrOwn, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True, ValidatesOnExceptions=True, ValidatesOnNotifyDataErrors=True}"></ComboBox>

在此示例中,我有一个具有RentOrOwn枚举属性的Applicant类。这将显示枚举中所有可用的值,然后在用户单击MVVM样式的新选定值时更新RentOrOwn属性。