WPF数据绑定:如何使用XAML将枚举数据绑定到combobox?

我上课了:

public class AccountDetail { public DetailScope Scope { get { return scope; } set { scope = value; } } public string Value { get { return this.value; } set { this.value = value; } } private DetailScope scope; private string value; public AccountDetail(DetailScope scope, string value) { this.scope = scope; this.value = value; } } 

和一个枚举:

 public enum DetailScope { Private, Business, OtherDetail } 

最后,我有一个.xaml文件:

      

我想做两件事:

  1. 我希望数据将DetailsScope枚举值绑定到combobox值。 我不希望直接绑定枚举值,因为最后一个枚举值是OtherDetail而不是Other detail (添加了空格字符和小写字母’d’)。
  2. 我希望将combobox中的选定值绑定到AccountDetail对象实例中指定的值。

你能救我吗? 谢谢。

更新:我发现这篇文章http://blogs.msdn.com/b/wpfsdk/archive/2007/02/22/displaying-enum-values-using-data-binding.aspx 。 我需要类似的东西。

一个非常简单的方法是使用ObjectDataProvider

      

使用ObjectDataProvider作为ComboBox的ItemsSource,将SelectedItem绑定到Scope属性并应用转换器来显示每个ComboBoxItem

        

在转换器中,您可以在此问题中使用Regex for CamelCase字符串拆分器。 我使用的是最先进的版本,但您可以使用更简单的版本。 OtherDetail +正则表达式=其他细节。 使返回值更低,然后返回带有第一个字符UpperCase的字符串应该给出预期的结果

 public class CamelCaseConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { string enumString = value.ToString(); string camelCaseString = Regex.Replace(enumString, "([az](?=[AZ])|[AZ](?=[AZ][az]))", "$1 ").ToLower(); return char.ToUpper(camelCaseString[0]) + camelCaseString.Substring(1); } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { return value; } } 

我一直这样做的方式如下。 这个解决方案的优点在于它完全通用,可以重复用于任何枚举类型。

1)定义枚举时,请使用一些自定义属性来提供一些信息。 在这个例子中,我使用了Browsable(false)来表示这个枚举器是内部的,我不想在combobox中看到这个选项。 描述(“”)允许我指定枚举的显示名称。

 public enum MyEnumerationTypeEnum { [Browsable(false)] Undefined, [Description("Item 1")] Item1, [Description("Item 2")] Item2, Item3 } 

2)定义一个我称之为EnumerationManager的类。 这是一个分析Enumeration类型并生成值列表的generics类。 如果枚举器将Browsable设置为false,则将跳过它。 如果它具有Description属性,那么它将使用描述字符串作为显示名称。 如果没有找到描述,它将只显示枚举器的默认字符串。

 public class EnumerationManager { public static Array GetValues(Type enumeration) { Array wArray = Enum.GetValues(enumeration); ArrayList wFinalArray = new ArrayList(); foreach(Enum wValue in wArray) { FieldInfo fi = enumeration.GetField(wValue.ToString()); if(null != fi) { BrowsableAttribute[] wBrowsableAttributes = fi.GetCustomAttributes(typeof(BrowsableAttribute),true) as BrowsableAttribute[]; if(wBrowsableAttributes.Length > 0) { // If the Browsable attribute is false if(wBrowsableAttributes[0].Browsable == false) { // Do not add the enumeration to the list. continue; } } DescriptionAttribute[] wDescriptions = fi.GetCustomAttributes(typeof(DescriptionAttribute),true) as DescriptionAttribute[]; if(wDescriptions.Length > 0) { wFinalArray.Add(wDescriptions[0].Description); } else wFinalArray.Add(wValue); } } return wFinalArray.ToArray(); } } 

3)在您的xaml中添加ResourceDictionary中的一个部分

       

4)现在只需将combobox的ItemsSource绑定到我们刚刚在资源字典中定义的这个键

  

如果您使用上面的枚举尝试此代码,您应该在combobox中看到3个项目:

 Item 1 Item 2 Item3 

希望这可以帮助。

编辑:如果您添加LocalizableDescriptionAttribute的实现,并使用它而不是我正在使用的Description属性将是完美的。

这是一个解决方案:您创建一个包含所有可能性的属性(列表),并在该属性上绑定您的ComboBox。

在XAML中:

  

并在代码背后:

 public partial class Window1 : Window { public Window1() { AccountDetailsProperty = new List() { new AccountDetail(DetailScope.Business, "Business"), new AccountDetail(DetailScope.OtherDetail, "Other details"), new AccountDetail(DetailScope.Private, "Private"), }; InitializeComponent(); this.DataContext = this; } public List AccountDetailsProperty { get; set; } } 

我会使用一个值转换器,这将允许您使用转换器直接绑定,您可以更改转换实现,以便为枚举的“更好”的人类可读表示,即拆分大写字符。

这里有一篇关于这种方法的完整文章。

  public class MyEnumToStringConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { return value.ToString(); } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { return (MyEnum) Enum.Parse( typeof ( MyEnum ), value.ToString(), true ); } }