Skip to content

Instantly share code, notes, and snippets.

@meziantou
Last active August 11, 2024 17:38
Show Gist options
  • Save meziantou/90730189693205fbf9d0 to your computer and use it in GitHub Desktop.
Save meziantou/90730189693205fbf9d0 to your computer and use it in GitHub Desktop.
WPF Enum
<StackPanel>
<StackPanel.Resources>
<ObjectDataProvider MethodName="GetValues" ObjectType="{x:Type sys:Enum}" x:Key="WeekDataProvider">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="demo:Week" />
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<demo:Week x:Key="WeekFirst">First</demo:Week>
<demo:EnumValueConverter x:Key="EnumValueConverter"/>
</StackPanel.Resources>
<TextBlock DataContext="{StaticResource WeekFirst}" Text="{Binding Converter={StaticResource EnumValueConverter}}"></TextBlock>
<ComboBox ItemsSource="{Binding Source={StaticResource WeekDataProvider}}">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Converter={StaticResource EnumValueConverter}}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<ComboBox ItemsSource="{demo:Enum demo:Week, UseDisplayAttribute=True}" />
<ComboBox ItemsSource="{demo:Enum demo:Week, UseDisplayAttribute=False}" />
</StackPanel>
[MarkupExtensionReturnType(typeof(IEnumerable<LocalizedValue>)]
public class EnumExtension : MarkupExtension
{
public EnumExtension()
{
}
public EnumExtension(Type enumType)
{
this.EnumType = enumType;
}
[ConstructorArgument("enumType")]
public Type EnumType { get; set; }
public bool UseDisplayAttribute { get; set; }
public override object ProvideValue(IServiceProvider serviceProvider)
{
if (EnumType == null)
throw new InvalidOperationException("The enum type is not set");
if (UseDisplayAttribute)
{
return LocalizationUtilities.GetEnumLocalization(EnumType);
}
return Enum.GetValues(this.EnumType).Cast<Enum>().Select(value => new LocalizedValue(value));
}
}
public class EnumValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var enumValue = value as Enum;
if (enumValue != null)
{
return LocalizationUtilities.GetEnumMemberLocalization(enumValue);
}
return string.Format("{0}", value);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
public static class LocalizationUtilities
{
private static readonly IDictionary<Type, LocalizedValueCollection> _enums = new Dictionary<Type, LocalizedValueCollection>();
private static readonly IDictionary<Expression, object> _properties = new Dictionary<Expression, object>();
public static LocalizedValueCollection GetEnumLocalization<T>() where T : struct
{
return GetEnumLocalization(typeof(T));
}
public static LocalizedValueCollection GetEnumLocalization(Type type)
{
LocalizedValueCollection value;
if (_enums.TryGetValue(type, out value))
{
return value;
}
IList<LocalizedValue> result = new List<LocalizedValue>();
Array enumValues = type.GetEnumValues();
foreach (object enumValue in enumValues)
{
var fieldInfo = type.GetField(enumValue.ToString());
DisplayAttribute displayAttribute = fieldInfo.GetCustomAttribute<DisplayAttribute>();
if (displayAttribute != null)
{
result.Add(new LocalizedValue(enumValue, displayAttribute));
}
else
{
result.Add(new LocalizedValue(enumValue, enumValue.ToString()));
}
}
LocalizedValueCollection localizedValueCollection = new LocalizedValueCollection(result);
_enums.Add(type, localizedValueCollection);
return localizedValueCollection;
}
public static string GetPropertyLocalization<T>(Expression<Func<T>> exp)
{
object value;
if (!_properties.TryGetValue(exp, out value))
{
MemberExpression memberExpression = (MemberExpression)exp.Body;
var displayAttribute = memberExpression.Member.GetCustomAttribute<DisplayAttribute>();
if (displayAttribute == null)
value = memberExpression.Member.Name;
else
value = displayAttribute.GetName();
_properties.Add(exp, value);
}
DisplayAttribute attribute = value as DisplayAttribute;
if (attribute != null)
{
return attribute.GetName();
}
return value.ToString();
}
public static string GetEnumMemberLocalization(Enum value)
{
if (value == null)
throw new ArgumentNullException("value");
var localizedValueCollection = GetEnumLocalization(value.GetType());
return localizedValueCollection[value].Name;
}
}
public class LocalizedValue
{
private readonly string _name;
private readonly object _value;
private readonly DisplayAttribute _displayAttribute;
public LocalizedValue(Enum value) : this(value, string.Format("{0}", value))
{
}
public LocalizedValue(object value, string name)
{
this._value = value;
this._name = name;
}
public LocalizedValue(object value, DisplayAttribute displayAttribute)
{
this._value = value;
_displayAttribute = displayAttribute;
}
public string Name
{
get
{
if (_displayAttribute != null)
return _displayAttribute.GetName();
return this._name;
}
}
public object Value
{
get
{
return this._value;
}
}
public override string ToString()
{
return Name;
}
}
public class LocalizedValueCollection : ReadOnlyCollection<LocalizedValue>
{
public LocalizedValueCollection(IList<LocalizedValue> list)
: base(list)
{
}
public new LocalizedValue this[int index]
{
get { return base[index]; }
}
public LocalizedValue this[object value]
{
get { return this.First(_ => _.Value.Equals(value)); }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment