具有泛型类的特定枚举转换的对象

时间:2018-04-19 23:21:58

标签: c# wpf enums type-conversion

我有几个枚举,我在几个ComboBox中的View as选项中显示。我正在使用转换器从缓存的属性字典中获取显示名称。当我明确地将对象作为特定的Enum转换到转换器中时没有问题(我使用参数对象和一个开关来确定哪个Enum要显式转换)但是,我想让这个控件更通用并且可用于任何我在视图中绑定的基于枚举的属性。

这是我在转换器上尝试的内容:

TagManager.Accounts.Containers.list(
    'accounts/' + accountId,
    {fields: 'container(name,publicId)'}
).container;

这是缓存字典对象:

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    if (value != null)
    {
        Type t = Nullable.GetUnderlyingType(value.GetType()) ?? value.GetType();
        var item = System.Convert.ChangeType(value, t);
        return item.GetEnumDisplayName();
    }
    else
        return DependencyProperty.UnsetValue;
}

&#34; GetEnumDisplayName&#34;的扩展方法未显示,但它只是将public static class EnumDisplayCache<T> //where T : struct, IComparable, IFormattable, IConvertible { private static Dictionary<T, string> _cache; static EnumDisplayCache() { _cache = new Dictionary<T, string>(); Type type = typeof(T); foreach (T e in Enum.GetValues(type).Cast<T>()) _cache.Add(e, e.GetDisplayName()); } public static string GetDisplayName(T value) { return _cache[value]; } } 传递给缓存字典。

这是例外:

  

提供的类型必须是枚举。

如何将该对象转换为其原始枚举?当我逐步调试调试器中的代码时,转换器中的类型似乎是正确的。

使用扩展方法更新:

T

使用XAML和ViewModel进行更新:

internal static string GetDisplayName<T>(this T enumValue) //where T : struct, IComparable, IFormattable, IConvertible
{
        return enumValue.GetType()?
                        .GetMember(enumValue.ToString())?
                        .First()?
                        .GetCustomAttribute<DisplayAttribute>()?
                        .GetName() ?? enumValue.ToString();
}

public static string GetEnumDisplayName<T>(this T value) //where T : struct, IComparable, IFormattable, IConvertible
{
    return EnumDisplayCache<T>.GetDisplayName(value);
}

视图模型:

<DataTemplate>
    <ComboBox ItemsSource="{Binding PossibleDimensions}"
                           SelectedItem="{Binding Dimensionality, Mode=TwoWay, UpdateSourceTrigger=LostFocus}">
        <ComboBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Converter={StaticResource enumToDisplayConverter}, 
                                                         ConverterParameter='dimensionality'}" />
            </DataTemplate>
         </ComboBox.ItemTemplate>
      </ComboBox>
</DataTemplate>

1 个答案:

答案 0 :(得分:0)

这不起作用,因为您在转换器中调用的System.Convert.ChangeType方法会返回object而不是Dimensionality。因此,您实际上是在调用object.GetEnumDisplayName而不是Dimensionality.GetEnumDisplayName

如果您取消注释类型约束,您将会看到更清晰,因为代码甚至无法编译。

如果你摆脱了非工作缓存,你的扩展方法将会起作用:

public static class EnumExtensions
{
    internal static string GetDisplayName<T>(this T enumValue) //where T : struct, IComparable, IFormattable, IConvertible
    {
        return enumValue.GetType()?
                        .GetMember(enumValue.ToString())?
                        .First()?
                        .GetCustomAttribute<DisplayAttribute>()?
                        .GetName() ?? enumValue.ToString();
    }

    public static string GetEnumDisplayName<T>(this T value) //where T : struct, IComparable, IFormattable, IConvertible
    {
        return GetDisplayName(value);
    }
}

但是你必须调用GetType()方法来获取当前枚举值的运行时类型。它是将System.Convert.ChangeType的结果转换为特定的枚举类型。没有什么&#34;泛型&#34;关于枚举类型。