[英]WPF How to bind an enum with Description to a ComboBox
如何將帶有Description
( DescriptionAttribute
) 的enum
綁定到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>
無法成功做到這一點,任何簡單的解決方案?
提前致謝!
這可以通過為您的組合框使用轉換器和項目模板來完成。
這是轉換器代碼,當綁定到枚舉時將返回描述值:
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>
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 });
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.