2010-10-21 113 views
30

是否可以使用ObjectDataProvider方法將ListBox綁定到枚舉,並以某種方式顯示描述屬性?如果是這樣,怎麼會這樣做...?WPF將ListBox綁定到枚舉,顯示Description屬性

+0

可能的重複http://stackoverflow.com/questions/1281490/binding-comboboxes-to-enums-in-silverlight。 – 2010-10-21 10:11:11

回答

79

是的,這是可能的。這將做到這一點。假設我們有枚舉

public enum MyEnum 
{ 
    [Description("MyEnum1 Description")] 
    MyEnum1, 
    [Description("MyEnum2 Description")] 
    MyEnum2, 
    [Description("MyEnum3 Description")] 
    MyEnum3 
} 

然後我們可以使用ObjectDataProvider的作爲

xmlns:MyEnumerations="clr-namespace:MyEnumerations" 
<ObjectDataProvider MethodName="GetValues" 
       ObjectType="{x:Type sys:Enum}" 
       x:Key="MyEnumValues"> 
    <ObjectDataProvider.MethodParameters> 
     <x:Type TypeName="MyEnumerations:MyEnum" /> 
    </ObjectDataProvider.MethodParameters> 
</ObjectDataProvider> 

併爲我們設置的ItemsSource到MyEnumValues列表框和一個轉換器適用於一個ItemTemplate。

<ListBox Name="c_myListBox" SelectedIndex="0" Margin="8" 
     ItemsSource="{Binding Source={StaticResource MyEnumValues}}"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <TextBlock Text="{Binding Converter={StaticResource EnumDescriptionConverter}}"/> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

而在轉換器我們得到了描述,並返回其

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

的GetEnumDescription方法或許應該去別的地方,但你的想法:)

+0

謝謝,現在就來試試這個:) – 2010-10-21 13:47:11

+4

愛它,狠狠揍它。我使用了一個小小的LINQ來配對GetEnumDescription,你可以在這裏找到http://pastebin.com/XLm9hbhG – Will 2010-12-15 16:21:14

+2

所以你必須爲每種類型的枚舉生成一個轉換器? – Carlo 2011-06-27 23:30:09

0

您可以定義的ressource文件在你的項目中(* .resx文件)。在這個文件中,你必須定義「鍵 - 值對的」,這樣的事情:

"YellowCars" : "Yellow Cars", 
"RedCars" : "Red Cars", 

等等...

是等於你的枚舉項中的按鍵,這樣的事情:

public enum CarColors 
{ 
    YellowCars, 
    RedCars 
} 

等等...

當您使用WPF,你可以在你的XAML的代碼實現,這樣的事:

<ComboBox ItemsSource="{Binding Source={StaticResource CarColors}}" SelectedValue="{Binding CarColor, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"> 
    <ComboBox.ItemTemplate> 
     <DataTemplate> 
      <TextBlock Text="{Binding Converter={StaticResource CarColorConverter}}" /> 
     </DataTemplate> 
    </ComboBox.ItemTemplate> 
</ComboBox> 

然後你必須寫你的轉換器,這樣的事情:

using System; 
using System.Globalization; 
using System.Resources; 
using System.Windows.Data; 

public class CarColorConverter : IValueConverter 
{ 
    private static ResourceManager CarColors = new ResourceManager(typeof(Properties.CarColors)); 

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     var key = ((Enum)value).ToString(); 
     var result = CarColors.GetString(key); 
     if (result == null) { 
      result = key; 
     } 

     return result; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

我的回答談到7年後期;-)但也許它可以被別人使用!