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

Bor*_*ris 24 c# data-binding 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

和一个枚举:

public enum DetailScope
{
    Private, 
    Business, 
    OtherDetail
}
Run Code Online (Sandbox Code Playgroud)

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

<Window x:Class="Gui.Wpf.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Test" 
    SizeToContent="WidthAndHeight">

    <Grid>
        <ComboBox 
            Name="ScopeComboBox" 
            Width="120" 
            Height="23" 
            Margin="12" />
    </Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)

我想做两件事:

  1. 我希望数据绑定DetailsScope枚举值到组合框值.我不希望直接绑定枚举值,因为最后的枚举值将OtherDetail代替 Other detail(添加空格字符和小写字母'd').
  2. 我希望数据将组合框中的选定值绑定到AccountDetail对象实例中指定的值.

你能救我吗?谢谢.

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

Fre*_*lad 41

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

<ObjectDataProvider MethodName="GetValues"
                    ObjectType="{x:Type sys:Enum}"
                    x:Key="DetailScopeDataProvider">
    <ObjectDataProvider.MethodParameters>
        <x:Type TypeName="local:DetailScope" />
    </ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
Run Code Online (Sandbox Code Playgroud)

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

<ComboBox Name="ScopeComboBox"
          ItemsSource="{Binding Source={StaticResource DetailScopeDataProvider}}"
          SelectedItem="{Binding Scope}"
          Width="120"
          Height="23"
          Margin="12">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Converter={StaticResource CamelCaseConverter}}"/>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>
Run Code Online (Sandbox Code Playgroud)

在转换器中,您可以在问题中使用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, "([a-z](?=[A-Z])|[A-Z](?=[A-Z][a-z]))", "$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;
    }
}
Run Code Online (Sandbox Code Playgroud)


Liz*_*Liz 11

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

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

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

2)定义一个我称之为EnumerationManager的类.这是一个泛型类,用于分析Enumeration类型并生成值列表.如果枚举器将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();
    }
  }
Run Code Online (Sandbox Code Playgroud)

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

  <ObjectDataProvider MethodName="GetValues" ObjectType="{x:Type l:EnumerationManager}" x:Key="OutputListForMyComboBox">
      <ObjectDataProvider.MethodParameters>
           <x:Type TypeName="l:MyEnumerationTypeEnum" />
      </ObjectDataProvider.MethodParameters>
  </ObjectDataProvider>
Run Code Online (Sandbox Code Playgroud)

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

<ComboBox Name="comboBox2" 
          ItemsSource="{Binding Source={StaticResource OutputListForMyComboBox}}" />
Run Code Online (Sandbox Code Playgroud)

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

Item 1
Item 2
Item3
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.

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