WPF ComboBox 中具有本地化名称的枚举
Enum in WPF ComboxBox with localized names
我有一个列出枚举的 ComboBox。
enum StatusEnum {
Open = 1, Closed = 2, InProgress = 3
}
<ComboBox ItemsSource="{Binding StatusList}"
SelectedItem="{Binding SelectedStatus}" />
我想用英文显示枚举值的本地化名称
Open
Closed
In Progress
还有德语(以及未来的其他语言)
Offen
Geschlossen
In Arbeit
在我的 ViewModel 中使用
public IEnumerable<StatusEnum> StatusList
{
get
{
return Enum.GetValues(typeof(StatusEnum)).Cast<StatusEnum>();
}
}
只得到代码中枚举的名称,而不是翻译后的名称。
我已经进行了一般本地化,可以使用
访问它们
Resources.Strings.InProgress
这让我得到当前语言的翻译。
如何自动绑定本地化?
你不能,开箱即用。
但是您可以创建一个 ObservableList<KeyValuePair<StatusEnum, string>>
属性 并用您的 enum/localized 文本填充它,然后将其绑定到您的 ComboBox
。
至于字符串本身:
var localizedText = (string)Application.Current.FindResource("YourEnumStringName");
使用 Enum.GetName
/Enum.GetNames
方法获取枚举字符串表示形式。
您可以为枚举使用属性并为枚举编写扩展方法。参考下面的代码。
<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.
}
}
我已经在 SO Is it possible to databind to a Enum, and show user-friendly values?
中发布了类似的内容
这是一个简单的 Enum
到已翻译字符串转换器的示例。
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");
}
}
您还需要一个 MarkupExtension
来提供值:
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;
}
}
用法:
<ComboBox ItemsSource="{local:Enumerate {x:Type local:StatusEnum}}"
SelectedItem="{Binding SelectedStatus, Converter={StaticResource EnumToStringConverter}}" />
编辑: 您可以创建更复杂的值转换器和标记扩展。 EnumToStringConverter
可以使用 DescriptionAttribute
来获取翻译后的字符串。而 EnumerateExtension
可以使用 TypeConverter.GetStandardValues()
和转换器。这允许获取指定类型的标准值(不仅是 Enum
s)并根据转换器将它们转换为字符串或其他内容。
示例:
<ComboBox ItemsSource="{local:Enumerate {x:Type sg:CultureInfo}, Converter={StaticResource CultureToNameConverter}}"
SelectedItem="{Binding SelectedCulture, Converter={StaticResource CultureToNameConverter}}" />
编辑: 上面描述的更复杂的解决方案现已发布在 GitHub 上。
我有一个列出枚举的 ComboBox。
enum StatusEnum {
Open = 1, Closed = 2, InProgress = 3
}
<ComboBox ItemsSource="{Binding StatusList}"
SelectedItem="{Binding SelectedStatus}" />
我想用英文显示枚举值的本地化名称
Open
Closed
In Progress
还有德语(以及未来的其他语言)
Offen
Geschlossen
In Arbeit
在我的 ViewModel 中使用
public IEnumerable<StatusEnum> StatusList
{
get
{
return Enum.GetValues(typeof(StatusEnum)).Cast<StatusEnum>();
}
}
只得到代码中枚举的名称,而不是翻译后的名称。
我已经进行了一般本地化,可以使用
访问它们Resources.Strings.InProgress
这让我得到当前语言的翻译。
如何自动绑定本地化?
你不能,开箱即用。
但是您可以创建一个 ObservableList<KeyValuePair<StatusEnum, string>>
属性 并用您的 enum/localized 文本填充它,然后将其绑定到您的 ComboBox
。
至于字符串本身:
var localizedText = (string)Application.Current.FindResource("YourEnumStringName");
使用 Enum.GetName
/Enum.GetNames
方法获取枚举字符串表示形式。
您可以为枚举使用属性并为枚举编写扩展方法。参考下面的代码。
<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.
}
}
我已经在 SO Is it possible to databind to a Enum, and show user-friendly values?
中发布了类似的内容这是一个简单的 Enum
到已翻译字符串转换器的示例。
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");
}
}
您还需要一个 MarkupExtension
来提供值:
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;
}
}
用法:
<ComboBox ItemsSource="{local:Enumerate {x:Type local:StatusEnum}}"
SelectedItem="{Binding SelectedStatus, Converter={StaticResource EnumToStringConverter}}" />
编辑: 您可以创建更复杂的值转换器和标记扩展。 EnumToStringConverter
可以使用 DescriptionAttribute
来获取翻译后的字符串。而 EnumerateExtension
可以使用 TypeConverter.GetStandardValues()
和转换器。这允许获取指定类型的标准值(不仅是 Enum
s)并根据转换器将它们转换为字符串或其他内容。
示例:
<ComboBox ItemsSource="{local:Enumerate {x:Type sg:CultureInfo}, Converter={StaticResource CultureToNameConverter}}"
SelectedItem="{Binding SelectedCulture, Converter={StaticResource CultureToNameConverter}}" />
编辑: 上面描述的更复杂的解决方案现已发布在 GitHub 上。