-1

我尝试找到使用绑定从资源中输出本地化枚举的解决方案。

现在我通过以下常用方式绑定枚举:

<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事件和显式转换。这可能吗?如果是,有人可以提供简单的代码示例吗?

4

3 回答 3

1

我认为如果你导入多个 xaml 文件来实现本地化是不可能的。

因为如果您将语言导入 xaml ,它们就是静态资源。我建议你使用绑定动态资源,并在cs文件中导入资源来初始化资源键。

Xaml 像这样:

 Content="{DynamicResource UID_AppCommon_MiniPA_Close}"

像这样:

this.Resources.MergedDictionaries.Add(your resource file);
于 2013-06-13T06:41:49.717 回答
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

请注意,它是struct而不是class。所以它是一个值类型,可以很容易地设置为SelectedItemaComboBoxListBox例如。

更进一步,您可以实现一个 IValueConverte 来进行简单的绑定:

/// <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;
    }
  }

然后你可以直接绑定SelectedItemenum类型:

<AttributeTypeToWrapperConverter x:Key="convertAttrTypeToWrapper"/>

<ComboBox ItemsSource="{Binding Path=DataTypes}"
          SelectedItem="{Binding Path=SelectedDataType, Converter={StaticResource convertAttrTypeToWrapper}}"/>

DataTypes是一个AttributeTypeWrapper结构数组。SelectedDataType是类型 AttributeType。(您也可以转换 ItemsSource)。

这对我来说很好。

于 2013-06-13T08:09:29.057 回答
0

我找到了另一种本地化枚举的方法:

这是我的课程,您可以以此为例:ru_RU 和 en_US - 资源文件名。

公共类 EnumLocalizationManager : BindableObject { 公共语言语言;私有的 CommonLocalization commonLang; 私有 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 { Auto = 0, Number = 1, Exponential = 2, Decimal = 3, Integer = 4 }

public enum RootConverterType
{
    Undefined = 0,
    Auto = 1,
    Number = 2,
    Exponential = 3,
    Decimal = 4,
    Integer = 5
}

最后一部分 - ValueConvert 本身:

类 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;
                }
            }

就这些。看起来有点吓人,但没有什么难的。

于 2013-09-16T16:55:41.647 回答