如何将带有Description的枚举绑定到组合框
本文关键字:绑定 枚举 组合 Description | 更新日期: 2023-09-27 18:05:11
如何将enum
与Description
(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>
不能成功做到这一点,有什么简单的解决方案吗?
提前感谢!
这可以通过为您的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();
}
}
虽然已经回答了,但我通常使用类型转换器执行以下操作。
-
我添加了一个类型转换器属性到我的枚举。
// MainWindow.cs, or any other class [TypeConverter(TypeOf(MyDescriptionConverter)] public enum ReportTemplate { [Description("Top view")] TopView, [Description("Section view")] SectionView }
-
实现类型转换器
// 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); }
-
提供一个属性来绑定
// 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>(); } } }
-
使用枚举属性绑定组合框。
<!-- 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 });