【问题标题】:WPF - Change string values of enum in combo boxWPF - 在组合框中更改枚举的字符串值
【发布时间】:2014-06-21 17:56:43
【问题描述】:

我有一个枚举,我使用它的值作为组合框中的选项。

枚举是这样的:

public enum TimeSizeEnum
{
    TENTHSECONDS,
    SECONDS,
    MINUTES,
    HOURS
}

我将值绑定到组合框的方式:

<ComboBox Grid.Row="4" Grid.Column="1" ItemsSource="{Binding Path=TimeSizeItemsSource, Converter={StaticResource TimerSizeConverter}}" SelectedItem="{Binding Path=TimeSize, Mode=TwoWay}" SelectedIndex="0" Margin="5" MinWidth="100"></ComboBox>

public string[] TimeSizeItemsSource
{
    get
    {
        return Enum.GetNames(typeof(TimeSizeEnum));
    }
}

我想用 TENTHSECONDS 代替 "Tenth of a second"SECONDS 代替 "Seconds"

我怎样才能做到这一点?价值转换器是最好的方法吗?但这意味着我需要对我想要的字符串进行硬编码?

【问题讨论】:

  • 答案的替代方法是使用 ValueConverter 和资源字典。考虑stackoverflow.com/questions/2787725/…
  • 我对所有枚举都使用了标记扩展,但它们使用的描述和类别属性很像值转换器。

标签: c# wpf combobox enums


【解决方案1】:

我建议使用DescriptionAttribute

public enum TimeSizeEnum
{
    [Description("Tenths of a second")]
    TENTHSECONDS,

    [Description("Seconds")]
    SECONDS,

    [Description("Minutes")]
    MINUTES,

    [Description("Hours")]
    HOURS
}

然后,您可以检查在 ValueConverter 中传递的 enum 值,从属性中读取描述,然后显示:

public class TimeSizeEnumDescriptionValueConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var type = typeof(TimeSizeEnum);
        var name = Enum.GetName(type, value);
        FieldInfo fi = type.GetField(name);
        var descriptionAttrib = (DescriptionAttribute)
            Attribute.GetCustomAttribute(fi, typeof(DescriptionAttribute));

        return descriptionAttrib.Description;
    }

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

要将值转换器应用于每个枚举值,您需要更改组合框的ItemTemplate 以包含值转换器:

<Window.Resources>
    <test:TimeSizeEnumDescriptionValueConverter x:Key="converter" />
</Window.Resources>

<!-- ... -->

<ComboBox ItemsSource="{Binding TimeSizeItemsSource}" >
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <ContentPresenter
                Content="{Binding Converter={StaticResource converter}}"/>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

【讨论】:

  • 你看到我将枚举绑定到 Combobox 的 ItemsSource 属性了吗?这意味着我在值转换器中获得了整个枚举值集(一个字符串 []),而不是枚举的单个值
  • 我在测试此解决方案时遇到了同样的问题,但它很容易解决 - 您需要将包含值转换器的 ContentPresenter 添加到组合框的 ItemTemplate 中以将其应用于每个enum 值。更新了我上面的答案。
  • 除非是用于非常小的应用程序,否则我强烈建议不要将DescriptionAttribute 用于与 UI 相关的任何内容。它不仅不可本地化,而且您可能还需要不同的描述来适应不同的 UI(短的、长的等)。
【解决方案2】:

您可以将属性放在枚举成员上,例如

public enum TimeSizeEnum
{
    [Description("Tenth of a second")]
    TENTHSECONDS,
    [Description("Seconds")]
    SECONDS,
}

然后您可以编写一个转换器,该转换器从传递的值中读取并返回这些属性,即在您可以编写的 IValueConveter 的 Convert 方法中

var enumtype = typeof(TimeSizeEnum);
var memInfo = enumtype.GetMember(value.ToString());
var attributes = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute),
    false);
var description = ((DescriptionAttribute)attributes[0]).Description;

return description

【讨论】:

  • 你看到我将枚举绑定到 Combobox 的 ItemsSource 属性了吗?这意味着我在值转换器中获得了整个枚举值集(一个字符串 []),而不是枚举的单个值
  • 除非是针对非常小的应用程序,否则我强烈建议不要将DescriptionAttribute 用于与 UI 相关的任何内容。它不仅不可本地化,而且您可能还需要不同的描述来适应不同的 UI(短的、长的等)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-03
  • 1970-01-01
  • 2018-11-12
  • 2020-02-07
  • 1970-01-01
相关资源
最近更新 更多