在Enum中填充的ListPicker中使用本地化字符串

and*_*ubi 2 c# data-binding enums combobox windows-phone-8

我填充一个ListPickerEnum.例如,如果我有以下枚举:

public enum Pets 
{
    Dog,
    Cat,
    Platypus 
}
Run Code Online (Sandbox Code Playgroud)

我通过以下方式填充ListPicker:

PetListPicker.ItemsSource = Enum.GetValues(typeof(Pets));
Run Code Online (Sandbox Code Playgroud)

一切都还好,直到那里.我的ListPicker控件显示要选择的项的名称.

问题是我想将Enum项本地化,以便以不同的语言使用它们.也就是说,我希望ListPicker以应用程序当前使用的语言显示名称.

我在资源文件中有本地化字符串,我用它来本地化应用程序的其余部分.但是,我不知道如何使它与ListPicker项一起使用.

and*_*ubi 6

我终于找到了一种方法来实现我的目标,使用Description属性为枚举值和a Converter.

由于无法将Resources文件中的值直接用作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);
    }
}
Run Code Online (Sandbox Code Playgroud)

这样我可以使用资源的ID作为LocalizedDescription属性:

public enum Pet
{
    [LocalizedDescription("Dog")]
    Dog,
    [LocalizedDescription("Cat")]
    Cat,
    [LocalizedDescription("Platypus")]
    Platypus 
}
Run Code Online (Sandbox Code Playgroud)

到了这里,我创建了一个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();
    }
}
Run Code Online (Sandbox Code Playgroud)

完成此操作后,我DataTemplate为ListPicker项创建了一个,通过a设置TextBlock的Text属性的值Binding并使用Converter:

<DataTemplate x:Key="ListPickerDataTemplate">
    <Grid>
        <TextBlock Text="{Binding Converter={StaticResource EnumToStringConverter}}"/>
    </Grid>
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)

我以与之前相同的方式填充ListPicker:

PetListPicker.ItemsSource = Enum.GetValues(typeof(Pet));
Run Code Online (Sandbox Code Playgroud)

现在我的ListPicker显示了项目的本地化值,其优点是SelectecItemListPicker 的属性可以绑定到Enum类型的属性.

例如,如果我的ViewModel中有以下属性,我想要存储所选项目:

public Pet MyPet {get; set;};
Run Code Online (Sandbox Code Playgroud)

我可以使用绑定:

<toolkit:ListPicker x:Name="MyListPicker" SelectedItem="{Binding MyPet, Mode=TwoWay}" ItemTemplate="{StaticResource ListPickerDataTemplate}"/>
Run Code Online (Sandbox Code Playgroud)