我尝试使用Binding找到从资源输出本地化枚举的解决方案。
现在我按照这样的常用方式绑定枚举:
<Page.Resources>
<ObjectDataProvider x:Key="RootConverterType" MethodName="GetValues" ObjectType="{x:Type sys:Enum}" >
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="settingsManager:RootConverterType"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<ComboBox ItemsSource="{Binding Source={StaticResource RootConverterType}}" SelectedValue="{Binding Path=CameraPosition.Config.UI.ValueConverterType.W, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
这不是本地化的枚举,但我希望使用本地化(使用资源中的不同语言),以及在没有ComboBox
事件和显式转换的情况下从本地化字符串转换为枚举。这可能吗?如果是的话,有人可以提供简单的代码示例吗?
答案 0 :(得分:1)
我认为如果你导入多个xaml文件来实现本地化是不可能的。
因为如果您将语言导入xaml,它们就是静态资源。我建议你使用绑定动态资源,并导入cs文件中的资源来初始化资源键。
Xaml像这样:
Content="{DynamicResource UID_AppCommon_MiniPA_Close}"
CS喜欢这个:
this.Resources.MergedDictionaries.Add(your resource file);
答案 1 :(得分:1)
我正在使用包装器结构来解决这个问题:
public enum AttributeType {
Bool,
Number,
String
}//AttributeType
public struct AttributeTypeWrapper {
public AttributeTypeWrapper(AttributeType type) {
this.type = type;
}
private AttributeType type;
public AttributeType Type {
get {
return type;
}
set {
type = value;
}
}
public override string ToString() {
switch(type) {
case AttributeType.Bool:
return Properties.Resources.txtBool;
case AttributeType.Number:
return Properties.Resources.txtNumber;
case AttributeType.String:
return Properties.Resources.txtString;
default:
return "Invalid AttributeType";
}
}
}// AttributeTypeWrapper
请注意,它是结构而不是类。因此,它是一种值类型,可以轻松设置为SelectedItem
或ComboBox
的{{1}}。
为了更进一步,您可以实现IValueConverte以进行简单绑定:
ListBox
然后,您可以将/// <summary>
/// Convert a AttributeType into its wrapper class to display strings from resources
/// in the selected language
/// </summary>
[ValueConversion(typeof(AttributeType), typeof(AttributeTypeWrapper))]
public class AttributeTypeToWrapperConverter : IValueConverter {
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
return new AttributeTypeWrapper((AttributeType)value);
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
return ((AttributeTypeWrapper)value).Type;
}
}
直接绑定到SelectedItem
类型:
enum
<AttributeTypeToWrapperConverter x:Key="convertAttrTypeToWrapper"/>
<ComboBox ItemsSource="{Binding Path=DataTypes}"
SelectedItem="{Binding Path=SelectedDataType, Converter={StaticResource convertAttrTypeToWrapper}}"/>
是一个DataTypes
结构数组。 AttributeTypeWrapper
属于类型
SelectedDataType
。 (您也可以转换ItemsSource。)
这对我来说非常好。
答案 2 :(得分:0)
我找到了另一种本地化枚举的方法:
这是我的课程,您可以使用以下示例: ru_RU和en_US - 资源文件名。
public class EnumLocalizationManager:BindableObject { 公共语言; private CommonLocalization commonLang; private ObservableCollection rootCoverterTypes;
public EnumLocalizationManager()
{
commonLang = CommonLocalization.GetInstance;
EnumLanguage = commonLang.Lang;
}
//Коллекция для локализации enum RootConverterType
public static Dictionary<Language, ObservableCollection<string>> RootConverterLocalization = new Dictionary<Language, ObservableCollection<string>>()
{
{
Language.ru_RU, new ObservableCollection<string>()
{
ru_RU.CameraEnumConverterTypeUndefined, ru_RU.CameraEnumConverterTypeAuto, ru_RU.CameraEnumConverterTypeNumber, ru_RU.CameraEnumConverterTypeExponent, ru_RU.CameraEnumConverterTypeDecimal, ru_RU.CameraEnumConverterTypeInteger
}
},
{
Language.en_US, new ObservableCollection<string>()
{
en_US.CameraEnumConverterTypeUndefined, en_US.CameraEnumConverterTypeAuto, en_US.CameraEnumConverterTypeNumber, en_US.CameraEnumConverterTypeExponent, en_US.CameraEnumConverterTypeDecimal, en_US.CameraEnumConverterTypeInteger
}
}
};
//Коллекция для локализации enum ConverterType
public static Dictionary<Language, ObservableCollection<string>> ConverterLocalization = new Dictionary<Language, ObservableCollection<string>>()
{
{
Language.ru_RU, new ObservableCollection<string>()
{
ru_RU.CameraEnumConverterTypeAuto, ru_RU.CameraEnumConverterTypeNumber, ru_RU.CameraEnumConverterTypeExponent, ru_RU.CameraEnumConverterTypeDecimal, ru_RU.CameraEnumConverterTypeInteger
}
},
{
Language.en_US, new ObservableCollection<string>()
{
en_US.CameraEnumConverterTypeAuto, en_US.CameraEnumConverterTypeNumber, en_US.CameraEnumConverterTypeExponent, en_US.CameraEnumConverterTypeDecimal, en_US.CameraEnumConverterTypeInteger
}
}
};
public ObservableCollection<string> RootConverterTypes
{
get { return rootCoverterTypes; }
}
public ObservableCollection<string> ConverterTypes
{
get { return coverterTypes; }
}
public Language EnumLanguage
{
get { return language; }
set
{
language = value;
ChangeEnumLanguage();
}
}
private void ChangeEnumLanguage()
{
if (RootConverterLocalization.ContainsKey(language))
{
rootCoverterTypes = RootConverterLocalization[language];
}
if (ConverterLocalization.ContainsKey(language))
{
coverterTypes = ConverterLocalization[language];
}
RaisePropertyChanged();
RaisePropertyChangedByName("RootConverterTypes");
RaisePropertyChangedByName("ConverterTypes");
}
}
}
BindableObject类是包含INotifyPropertyChanged的类。 首先 - 你的枚举必须编号(ValueConverter需要它) 对于前: public enum ConverterType { 自动= 0, 数字= 1, 指数= 2, 十进制= 3, 整数= 4 }
public enum RootConverterType
{
Undefined = 0,
Auto = 1,
Number = 2,
Exponential = 3,
Decimal = 4,
Integer = 5
}
和最后一部分 - ValueConvert本身:
class EnumCameraVariantToLocalizedStringConverter:ConverterBase { public EnumCameraVariantToLocalizedStringConverter() {
}
public override object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
return (int)(CameraVariant)value;
}
public override object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
int index = (int)value;
switch (index)
{
case 0:
return CameraVariant.Undefined;
case 1:
return CameraVariant.FirstPerson;
case 2:
return CameraVariant.ThirdPerson;
case 3:
return CameraVariant.Flight;
}
return index;
}
}
我使用基类的继承只是为了使用makrup扩展而不为每个转换器添加资源。
绑定本身:
<ComboBox Style="{StaticResource CameraMainSelectorStyle}"
ItemsSource="{Binding Source={StaticResource EnumLocalizationManager}, Path=CameraVariant}"
SelectedIndex="{Binding Path=CameraSettingsManager.StartUpCameraModeFilter, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Converter={valueConverters:EnumCameraVariantToLocalizedStringConverter}}"
Tag="{Binding Path=CameraSettingsManager.StartUpCameraModeFilter, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"
SelectionChanged="StartUpCameraTypeFilter_OnSelectionChanged"/>
这是Combobox的绑定枚举。我希望事情很清楚。这里有一件事。如果您想在飞行中更改语言,则必须添加一些代码,以便在语言更改后不丢失所选项目:
if (((ComboBox)sender).SelectedIndex < 0)
{
if (((ComboBox) sender).Tag != null)
{
CameraVariant behavior = (CameraVariant) ((ComboBox) sender).Tag;
((ComboBox) sender).SelectedIndex = (int) behavior;
}
}
这一切。看起来有点可怕,但没有什么难的。