WPF如何将带有描述的枚举绑定到组合框

时间:2013-03-22 10:20:14

标签: c# wpf combobox devexpress enumeration

您好我想将enum与描述绑定到组合框:

我接下来的枚举:

  public enum ReportTemplate
  {
     [Description("Top view")]
     1,
     [Description("Section view")]
     2
  }

我试过了:

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

无法成功做到这一点1知道一个简单的解决方案吗?

提前致谢!

4 个答案:

答案 0 :(得分:12)

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

这是转换器代码,当绑定到枚举时将返回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中你需要使用和项目模板。

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

答案 1 :(得分:0)

RSmaller有一个很好的答案,也是我使用的那个,有一点需要注意。如果您的枚举上有多个属性,并且描述不是第一个列出,那么他的“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();
        }
    }

答案 2 :(得分:0)

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

  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 保持可读性。 如果缺少枚举项属性之一,则使用项本身的名称。

答案 3 :(得分:-3)

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