【问题标题】:WPF How to bind an enum with Description to a ComboBoxWPF如何将带有描述的枚举绑定到组合框
【发布时间】:2013-03-22 10:20:14
【问题描述】:

如何将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>

无法成功,有什么简单的解决方案吗?

提前致谢!

【问题讨论】:

标签: c# wpf combobox devexpress enumeration


【解决方案1】:

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

这是绑定到枚举时将返回描述值的转换器代码:

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>

【讨论】:

  • 什么是 MyEnums 和 MySelectedItem?
  • 是的,这个解决方案是最好的
【解决方案2】:

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

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:
      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 });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-11-12
        • 2020-02-07
        • 2018-12-18
        • 2011-08-04
        • 2015-08-20
        • 2010-10-09
        相关资源
        最近更新 更多