如何将ComboBox与DataTemplate中的所有枚举类型绑定?

时间:2013-11-16 18:11:08

标签: c# wpf xaml combobox enums

我想根据绑定类型显示框架UI元素。 对于枚举类型,我想显示ComboBox。

我已经在xaml中有这个部分:

<StackPanel Grid.Column="2">
   <StackPanel.Resources>

       <ObjectDataProvider x:Key="EnumValues" ObjectType="{x:Type sys:Enum}" MethodName="GetValues">
            <ObjectDataProvider.MethodParameters>
                 <x:Type TypeName= <-- How to indicate for all enum types? --> >
            </ObjectDataProvider.MethodParameters>
       </ObjectDataProvider>

       <DataTemplate DataType="{x:Type sys:String}">
            <TextBox Text="{Binding Content, RelativeSource={RelativeSource AncestorType=ContentPresenter}, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Width="100" HorizontalAlignment="Left" VerticalAlignment="Center" BorderThickness="0" />
       </DataTemplate>
       <DataTemplate DataType="{x:Type sys:Double}">
            <TextBox Text="{Binding Content, RelativeSource={RelativeSource AncestorType=ContentPresenter}, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Width="100" HorizontalAlignment="Left" VerticalAlignment="Center" BorderThickness="0"/>
       </DataTemplate>
       <DataTemplate DataType="{x:Type sys:Enum}">
            <ComboBox ItemsSource="{Binding Source={StaticResource EnumValues}}"  SelectedValue="{Binding Content, RelativeSource={RelativeSource AncestorType=ContentPresenter}, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Width="100" HorizontalAlignment="Left" VerticalAlignment="Center" BorderThickness="0"/>
       </DataTemplate>

   </StackPanel.Resources>
   <ContentPresenter Content="{Binding Value, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" />
</StackPanel>

有没有办法在xaml上执行此操作?

更新: 目前,我使用2个转换器解决了它。 第一个返回ItemsSource的给定枚举中的字符串集合:

    /// <summary>
    /// Converts the given value into a collection of strings
    /// </summary>
    /// <returns>collection of strings</returns>
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value != null)
        {
            IEnumerable<Enum> enumsCollection = value.GetType().GetEnumValues().Cast<Enum>();
            return enumsCollection.Select(enumValue => enumValue.ToString());
        }
        return null;
    }

对于SelectedValue,第二个将枚举转换为字符串,反之亦然:

public class EnumToStringConverter : IValueConverter
    {
        #region Properties

        /// <summary>
        /// Last target type to be converted
        /// </summary>
        protected Type LastTargetType { get; set; }

        #endregion

        #region IValueConverter Members

        /// <summary>
        /// Converts a given value into a string representation
        /// </summary>
        /// <returns>string</returns>
        public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value != null)
            {
                LastTargetType = value.GetType();
                return value.ToString();
            }

            return null;
        }

        /// <summary>
        /// Converts back a given value into an enum representation
        /// </summary>
        /// <returns>enum</returns>
        public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return Enum.Parse(LastTargetType, value.ToString());
        }

        #endregion
    }

XAML中的ComboBox定义如下:

                                    <DataTemplate DataType="{x:Type sys:Enum}">
                                        <ComboBox Name="EnumComboBox" ItemsSource="{Binding Content, RelativeSource={RelativeSource AncestorType=ContentPresenter}, Converter={StaticResource EnumValuesConv}, Mode=OneTime}"  SelectedValue="{Binding Content, Converter={StaticResource EnumToStringConv}, RelativeSource={RelativeSource AncestorType=ContentPresenter}, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Focusable="False" Width="100" Background="Transparent" HorizontalAlignment="Left" VerticalAlignment="Center" BorderThickness="0">
                                            <ComboBox.ItemTemplate>
                                                <DataTemplate>
                                                    <TextBlock Text="{Binding}"/>
                                                </DataTemplate>
                                            </ComboBox.ItemTemplate>
                                        </ComboBox>
                                    </DataTemplate>

2 个答案:

答案 0 :(得分:0)

请看一下这个:

  <Window.Resources>
    <ObjectDataProvider MethodName="GetValues"
                        ObjectType="{x:Type sys:Enum}"
                        x:Key="AlignmentValues">
      <ObjectDataProvider.MethodParameters>
        <x:Type TypeName="HorizontalAlignment" />
      </ObjectDataProvider.MethodParameters>
    </ObjectDataProvider>
  </Window.Resources>

顺便说一句谷歌是你的朋友。在发布此处之前,请先咨询谷歌。

在发布答案之前我也这样做了,我找到了这个链接

http://msdn.microsoft.com/en-us/library/bb613576.aspx

答案 1 :(得分:0)

您发布的解决方案有点缺陷,因为它不能同时处理不同类型的枚举(即您不能将两个组合框绑定到不同的枚举类型) 。通过稍微修改它,我得到了一个适用于所有情况的简单解决方案。

如果不将枚举值转换为字符串,而是将它们保留为枚举,则可以直接绑定到SelectedValue,而无需使用其他转换器。

xaml看起来像这样

<ComboBox ItemsSource="{Binding Path=Value, Converter={StaticResource EnumValuesConverter}, Mode=OneTime}"
          SelectedValue="{Binding Path=Value, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>

这是转换器

public class EnumValuesConverter : IValueConverter
{
    /// <summary>
    /// Converts the given value into a collection of enum values
    /// </summary>
    /// <returns>collection of strings</returns>
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value != null)
        {
            IEnumerable<Enum> enumsCollection = value.GetType().GetEnumValues().Cast<Enum>();
            return enumsCollection;
        }
        return null;
    }

    /// <summary>
    /// Converts back a given value. Not supported for this converter.
    /// </summary>
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotSupportedException("EnumValuesConverter is a OneWay converter.");
    }

}

当然,此处显示的名称将是您在枚举中定义的名称。如果您希望您的姓名更加用户友好,请查看http://www.codeproject.com/Articles/29495/Binding-and-Using-Friendly-Enums-in-WPF