2013-06-13 24 views
-1

我嘗試找到使用Binding從資源輸出本地枚舉的解決方案。使用綁定和不同語言進行Enum本地化

現在我綁定枚舉通過這樣的常見方式:

<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事件和顯式轉換的枚舉。這可能嗎?如果是的話,有人可以提供簡單的代碼示例嗎?

回答

1

我認爲這是不可能的,如果你導入多個xaml文件來實現本地化。

因爲如果您將語言導入xaml,它們是靜態資源。我建議你使用綁定動態資源,並在cs文件中導入資源來初始化資源密鑰。

XAML中像這樣:

Content="{DynamicResource UID_AppCommon_MiniPA_Close}" 

CS像這樣:

this.Resources.MergedDictionaries.Add(your resource file); 
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不是。所以它是一種數值類型,例如可以簡單地設置爲ComboBoxListBoxSelectedItem

再向前邁進一步,你可以實現一個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}}"/> 

DataTypesAttributeTypeWrapper數組結構。 SelectedDataType類型爲 AttributeType。 (你也可以轉換ItemsSource)。

這對我來說很不錯。

+0

這裏有點問題。我完全一樣,只是空的組合框。你確定這足夠嗎? – Denis

+0

是的,我確定。你是否正確設置了DataContext? – Buchter

+0

當然,我已經完成了本地化。 – Denis

0

我找到了另一種方式來本地化枚舉:

這裏是我的班,你可以使用ASE一個例子: ru_RU和EN_US - 資源的文件名。

public class EnumLocalizationManager:BindableObject { public language language; 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類是類incapsulates INotifyPropertyChanged的。所有的 首先 - 您的枚舉必須編號(它需要ValueConverter) 爲前: 公共枚舉ConverterType { 自動= 0, 總數= 1, 指數= 2, 小數= 3, 整數= 4 }

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

和最後一部分 - ValueConvert本身:

類EnumCameraVariantToLocalizedStringConverter:ConverterBase { 公共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 extenstions無需增加資源爲每個轉換器。

和結合自身:

<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"/> 

這裏是綁定枚舉組合框。我希望事情很清楚。這裏有一件事。如果您想更改語言,您必須添加一些代碼,以便在語言更改後不會丟失選定的項目:

if (((ComboBox)sender).SelectedIndex < 0) 
      { 
       if (((ComboBox) sender).Tag != null) 
       { 
        CameraVariant behavior = (CameraVariant) ((ComboBox) sender).Tag; 
        ((ComboBox) sender).SelectedIndex = (int) behavior; 
       } 
      } 

這一切。看起來有點可怕,但沒有什麼困難。