Enum in WPF ComboxBox with localized names
It's an example of the simple Enum
to translated string converter.
public sealed class EnumToStringConverter : IValueConverter{ public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { if (value == null) { return null; } return Resources.ResourceManager.GetString(value.ToString()); } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { string str = (string)value; foreach (object enumValue in Enum.GetValues(targetType)) { if (str == Resources.ResourceManager.GetString(enumValue.ToString())) { return enumValue; } } throw new ArgumentException(null, "value"); }}
Also you need a MarkupExtension
which will provide values:
public sealed class EnumerateExtension : MarkupExtension{ public Type Type { get; set; } public EnumerateExtension(Type type) { this.Type = type; } public override object ProvideValue(IServiceProvider serviceProvider) { string[] names = Enum.GetNames(Type); string[] values = new string[names.Length]; for (int i = 0; i < names.Length; i++) { values[i] = Resources.ResourceManager.GetString(names[i]); } return values; }}
Usage:
<ComboBox ItemsSource="{local:Enumerate {x:Type local:StatusEnum}}" SelectedItem="{Binding SelectedStatus, Converter={StaticResource EnumToStringConverter}}" />
EDIT: You can make a more complex value converter and markup extension. The EnumToStringConverter
can use DescriptionAttribute
's to get the translated strings. And the EnumerateExtension
can use TypeConverter.GetStandardValues()
and a converter. This allows to get standard values of the specified type (not only Enum
s) and convert them to strings or something another depending on the converter.
Example:
<ComboBox ItemsSource="{local:Enumerate {x:Type sg:CultureInfo}, Converter={StaticResource CultureToNameConverter}}" SelectedItem="{Binding SelectedCulture, Converter={StaticResource CultureToNameConverter}}" />
EDIT: The more complex solution described above is published on GitHub now.
You can do using a Attribute for the enum and writing an extension method for the enum. Refer the below code.
<ComboBox Width="200" Height="25" ItemsSource="{Binding ComboSource}" DisplayMemberPath="Value" SelectedValuePath="Key"/>public class MainViewModel{ public List<KeyValuePair<Status, string>> ComboSource { get; set; } public MainViewModel() { ComboSource = new List<KeyValuePair<Status, string>>(); Status st=Status.Open; ComboSource = re.GetValuesForComboBox<Status>(); }}public enum Status{ [Description("Open")] Open, [Description("Closed")] Closed, [Description("InProgress")] InProgress} public static class ExtensionMethods { public static List<KeyValuePair<T, string>> GetValuesForComboBox<T>(this Enum theEnum) { List<KeyValuePair<T, string>> _comboBoxItemSource = null; if (_comboBoxItemSource == null) { _comboBoxItemSource = new List<KeyValuePair<T, string>>(); foreach (T level in Enum.GetValues(typeof(T))) { string Description = string.Empty; FieldInfo fieldInfo = level.GetType().GetField(level.ToString()); DescriptionAttribute[] attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false); if (attributes != null && attributes.Length > 0) { Description = GetDataFromResourceFile(attributes.FirstOrDefault().Description); } KeyValuePair<T, string> TypeKeyValue = new KeyValuePair<T, string>(level, Description); _comboBoxItemSource.Add(TypeKeyValue); } } return _comboBoxItemSource; } public static string GetDataFromResourceFile(string key) { //Do you logic to get from resource file based on key for a language. } }
I have already posted a similar thing in SO Is it possible to databind to a Enum, and show user-friendly values?
You can't, out of the box.
But you can create an ObservableList<KeyValuePair<StatusEnum, string>>
property and fill it with your enum/localized text and then bind it to your ComboBox
.
As for the string itself:
var localizedText = (string)Application.Current.FindResource("YourEnumStringName");
Getting the Enum string representation with Enum.GetName
/Enum.GetNames
methods.