如何将带有Description的枚举绑定到组合框

本文关键字:绑定 枚举 组合 Description | 更新日期: 2023-09-27 18:05:11

如何将enumDescription (DescriptionAttribute)绑定到ComboBox ?

我得到了一个enum:

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

我试过了:

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

不能成功做到这一点,有什么简单的解决方案吗?

提前感谢!

如何将带有Description的枚举绑定到组合框

这可以通过为您的comboBox使用转换器和项模板来完成。

下面是转换器代码,当绑定到enum时将返回Description值:

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

然后在你的xaml中你需要使用item模板。

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

RSmaller有一个很好的答案,也是我使用的,但有一点需要注意。如果你的枚举中有多个属性,并且Description不是第一个列出的,那么他的"GetEnumDescription"方法将抛出异常…

这里是一个稍微安全的版本:

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

虽然已经回答了,但我通常使用类型转换器执行以下操作。

  1. 我添加了一个类型转换器属性到我的枚举。

    // MainWindow.cs, or any other class
    [TypeConverter(TypeOf(MyDescriptionConverter)]
    public enum ReportTemplate
    { 
         [Description("Top view")]
         TopView,
         [Description("Section view")]
         SectionView
    }
    
  2. 实现类型转换器

    // Converters.cs
    public class MyDescriptionConverter: EnumConverter
    {
        public MyDescriptionConverter(Type type) : base(type) { }
        public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
        {
             if (destinationType == typeof(string))
             {
                 if (value != null)
                 {
                     FieldInfo fieldInfo = value.GetType().GetField(value.ToString());
                 if (fieldInfo != null)
                 {
                     var attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false);
                     return ((attributes.Length > 0) && (!string.IsNullOrEmpty(attributes[0].Description))) ? attributes[0].Description : value.ToString();
                 }
             }
             return string.Empty;
         }
         return base.ConvertTo(context, culture, value, destinationType);
     }
    
  3. 提供一个属性来绑定

    // myclass.cs, your class using the enum
    public class MyClass()
    {
        // Make sure to implement INotifyPropertyChanged, but you know how to do it
        public MyReportTemplate MyReportTemplate { get; set; }
        // Provides the bindable enumeration of descriptions
        public IEnumerable<ReportTemplate> ReportTemplateValues
        {
             get { return Enum.GetValues(typeof(ReportTemplate)).Cast<ReportTemplate>(); }
        }
    }
    
  4. 使用枚举属性绑定组合框。

     <!-- MainWindow.xaml -->
     <ComboBox ItemsSource="{Binding ReportTemplateValues}"
               SelectedItem="{Binding MyReportTemplate}"/>
     <!-- Or if you just want to show the selected vale -->
     <TextBlock Text="MyReportTemplate"/>
    

我喜欢这种方式,我的xaml保持可读性。如果缺少枚举项属性之一,则使用项本身的名称。

public enum ReportTemplate
{
 [Description("Top view")]
 Top_view=1,
 [Description("Section view")]
 Section_view=2
}
ComboBoxEditSettings.ItemsSource = EnumHelper.GetAllValuesAndDescriptions(new
List<ReportTemplate> { ReportTemplate.Top_view, ReportTemplate.Section_view });