我正在从ListPicker
填充Enum
。例如,如果我有以下枚举:
public enum Pets
{
Dog,
Cat,
Platypus
}
我通过以下方式填充ListPicker:
PetListPicker.ItemsSource = Enum.GetValues(typeof(Pets));
一切正常,直到那里。我的ListPicker控件显示了要选择的项目的名称。
问题是我想本地化该Enum项以在不同的语言中使用它们。也就是说,我希望ListPicker以应用程序当前使用的语言显示名称。
我在资源文件中有本地化字符串,用于本地化应用程序的其余部分。但是,我不知道如何使其与ListPicker项一起使用。
最佳答案
我终于找到了一种使用枚举值的Description
属性和Converter
实现目标的方法。
由于不可能将资源文件中的值直接用作Description属性,因此我首先创建了自定义LocalizedDescriptionAttribute类,该类继承自DescriptionAttribute:
public class LocalizedDescriptionAttribute : DescriptionAttribute
{
public LocalizedDescriptionAttribute(string resourceId)
: base(GetStringFromResource(resourceId))
{ }
private static string GetStringFromResource(string resourceId)
{
return AppResources.ResourceManager.GetString(resourceId);
}
}
这样,我可以将资源的ID用作LocalizedDescription属性:
public enum Pet
{
[LocalizedDescription("Dog")]
Dog,
[LocalizedDescription("Cat")]
Cat,
[LocalizedDescription("Platypus")]
Platypus
}
到了这里,我创建了一个
ValueConverter
,它可以在ListPicker中以适当的语言显示字符串:public class EnumToStringConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value != null)
{
Type type = value.GetType();
string name = Enum.GetName(type, value);
if (name != null)
{
FieldInfo field = type.GetField(name);
if (field != null)
{
DescriptionAttribute attr =
Attribute.GetCustomAttribute(field,
typeof(DescriptionAttribute)) as DescriptionAttribute;
if (attr != null)
{
return attr.Description;
}
}
}
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
为此,我为ListPicker项目创建了
DataTemplate
,通过Binding
并使用Converter
设置了TextBlock的Text属性的值:<DataTemplate x:Key="ListPickerDataTemplate">
<Grid>
<TextBlock Text="{Binding Converter={StaticResource EnumToStringConverter}}"/>
</Grid>
</DataTemplate>
然后以与之前相同的方式填充ListPicker:
PetListPicker.ItemsSource = Enum.GetValues(typeof(Pet));
现在,我的ListPicker显示了项的本地化值,其优点是ListPicker的
SelectecItem
属性可以绑定到Enum类型的属性。例如,如果我在ViewModel中具有以下属性,则要在其中存储所选项目:
public Pet MyPet {get; set;};
我可以使用绑定:
<toolkit:ListPicker x:Name="MyListPicker" SelectedItem="{Binding MyPet, Mode=TwoWay}" ItemTemplate="{StaticResource ListPickerDataTemplate}"/>