我正在从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}"/>

10-08 13:53