转换器显示枚举的描述,并在从wpf的组合框中选择项目时转换回枚举值

aro*_*ore 14 .net c# wpf enums converter

我正在使用枚举来在我的组合框中登记值.我想写一个转换器,它将显示所选枚举值的"描述".并且,选中后,它将返回枚举值.

大多数在线转换器都没有实现ConvertBack()方法(这就是我在这里发布的原因).

提前致谢.

sth*_*ura 18

这是ConvertBack方法:

public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    return value;
}
Run Code Online (Sandbox Code Playgroud)

完整转换器代码:

public class EnumConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value == null) return DependencyProperty.UnsetValue;

        return GetDescription((Enum)value);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value;
    }

    public static string GetDescription(Enum en)
    {
        Type type = en.GetType();
        MemberInfo[] memInfo = type.GetMember(en.ToString());
        if (memInfo != null && memInfo.Length > 0)
        {
            object[] attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
            if (attrs != null && attrs.Length > 0)
            {
                return ((DescriptionAttribute)attrs[0]).Description;
            }
        }
        return en.ToString();
    }
}
Run Code Online (Sandbox Code Playgroud)

编辑

这是我的ComboBox XAML:

<ComboBox ItemsSource="{Binding SampleValues}" 
          SelectedItem="{Binding SelectedValue, Converter={StaticResource enumConverter}}">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Path=., Converter={StaticResource enumConverter}}" />
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>
Run Code Online (Sandbox Code Playgroud)

编辑2:

我最初有一个不正确的XAML,我绑定__CODE____CODE__,而不是__CODE__.这就是我必须__CODE__在我的__CODE__方法中使用的原因.在修复XAML并通过调试器运行样本后,我意识到我可以__CODE____CODE__方法返回,因为值本身是__CODE__类型.


Joe*_*Joe 6

我知道这是一个古老的问题,但是由于某种原因,这似乎相当复杂(尽管我目前正在UWP应用上执行此任务),这相当复杂。结合使用已接受的答案,我发现的其他一些项目以及自己的一些工作,这是我发现完成这项艰巨任务的最简单方法。简而言之:

  • 通过在Display属性中设置说明来定义您的枚举
  • 创建一个将枚举值转换为描述的转换器
  • 在您的视图模型中,公开从中选择的枚举值的集合,即选定的枚举值,然后将其初始化
  • 定义几个方便的枚举扩展方法
  • 最后,对ComboBox进行一些简单的绑定,只是重写其ItemTemplate以使用转换器。

枚举

public enum EnumOptions
{
    [Display(Description = "Option 1")]
    OptionOne= 1,
    [Display(Description = "Option 2")]
    OptionTwo,
    [Display(Description = "Option 3")]
    OptionThree
}
Run Code Online (Sandbox Code Playgroud)

转换器

public class EnumToDisplayConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        var enumValue = value as Enum;

        return enumValue == null ? DependencyProperty.UnsetValue : enumValue.GetDescriptionFromEnumValue();
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        return value;
    }
}
Run Code Online (Sandbox Code Playgroud)

视图模型(局部)

public IReadOnlyList<EnumOptions> Options { get; }

private EnumOptions _selectedOption;

public EnumOptions SelectedOption
{
    get { return _selectedOption; }
    set
    {
        _selectedOption = value;
        OnPropertyChanged(() => SelectedOption);
    }
}

// Initialization in constructor
Options = EnumExtensions.GetValues<EnumOptions>().ToArray();
// If you want to set a default.
SelectedOption = Options[0];
Run Code Online (Sandbox Code Playgroud)

扩展名

public static class EnumExtensions
{
    public static string GetDescriptionFromEnumValue(this Enum value)
    {
        var attribute = value.GetType()
            .GetField(value.ToString())
            .GetCustomAttributes(typeof(DisplayAttribute), false)
            .SingleOrDefault() as DisplayAttribute;
        return attribute == null ? value.ToString() : attribute.Description;
    }

    /// <summary>
    /// Enumerates all enum values
    /// </summary>
    /// <typeparam name="T">Enum type</typeparam>
    /// <returns>IEnumerable containing all enum values</returns>
    /// <see cref="http://stackoverflow.com/questions/972307/can-you-loop-through-all-enum-values"/>
    public static IEnumerable<T> GetValues<T>()
    {
        return Enum.GetValues(typeof (T)).Cast<T>();
    }
}
Run Code Online (Sandbox Code Playgroud)

XAML(部分)

<TextBlock Grid.Row="1">Choose an option</TextBlock>
<ComboBox Grid.Row="2"
          ItemsSource="{Binding Options}"
          SelectedItem="{Binding SelectedOption, Mode=TwoWay}">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Converter={StaticResource EnumToDisplayConverter}}"></TextBlock>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>
Run Code Online (Sandbox Code Playgroud)