2015-04-15 1 views
12

मेरे पास एक कॉम्बोबॉक्स एक एनम सूचीबद्ध है।स्थानीय नामों के साथ WPF ComboxBox में Enum

enum StatusEnum { 
    Open = 1, Closed = 2, InProgress = 3 
} 

<ComboBox ItemsSource="{Binding StatusList}" 
      SelectedItem="{Binding SelectedStatus}" /> 

मैं अंग्रेजी में enum मूल्यों के लिए स्थानीय नाम प्रदर्शित करने के

Open 
Closed 
In Progress 

चाहते हैं, लेकिन यह भी जर्मन (और भविष्य में अन्य भाषाओं)

Offen 
Geschlossen 
In Arbeit 

मेरी ViewModel में

का उपयोग कर
public IEnumerable<StatusEnum> StatusList 
{ 
    get 
    { 
     return Enum.GetValues(typeof(StatusEnum)).Cast<StatusEnum>(); 
    } 
} 

केवल मुझे कोड में enum के नाम मिल जाता है, न कि अनुवादित।

मैं जगह में सामान्य स्थानीयकरण है और अर्थात का उपयोग कर

Resources.Strings.InProgress 

जो मुझे वर्तमान भाषा के लिए अनुवाद हो जाता है उन तक पहुँच सकते हैं।

कैसे मैं अपने आप स्थानीयकरण बाध्य कर सकते हैं?

+0

क्या आपके पास पहले से ही किसी प्रकार की स्थानीयकरण प्रणाली है? यदि हां, तो विवरण? या क्या हमें आपको 'स्ट्रिंग GetValue (StatusEnum स्थिति)' विधि पर ले जाना चाहिए और आपको वहां से स्थानांतरित करने देना चाहिए? –

+0

मेरे पास स्थान पर स्थानीयकरण है। मुझे सिर्फ बाध्यकारी के लिए इसे समझने की आवश्यकता है, –

उत्तर

14

में एक ऐसी ही बात पोस्ट किया है यह अनुवादित स्ट्रिंग कनवर्टर करने के लिए सरल Enum का एक उदाहरण है।

public sealed class EnumToStringConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     if (value == null) 
     { return null; } 

     return Resources.ResourceManager.GetString(value.ToString()); 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     string str = (string)value; 

     foreach (object enumValue in Enum.GetValues(targetType)) 
     { 
      if (str == Resources.ResourceManager.GetString(enumValue.ToString())) 
      { return enumValue; } 
     } 

     throw new ArgumentException(null, "value"); 
    } 
} 

इसके अलावा, आप एक MarkupExtension जरूरत है जो मान प्रदान करेगा:

public sealed class EnumerateExtension : MarkupExtension 
{ 
    public Type Type { get; set; } 

    public EnumerateExtension(Type type) 
    { 
     this.Type = type; 
    } 

    public override object ProvideValue(IServiceProvider serviceProvider) 
    { 
     string[] names = Enum.GetNames(Type); 
     string[] values = new string[names.Length]; 

     for (int i = 0; i < names.Length; i++) 
     { values[i] = Resources.ResourceManager.GetString(names[i]); } 

     return values; 
    } 
} 

उपयोग:

<ComboBox ItemsSource="{local:Enumerate {x:Type local:StatusEnum}}" 
      SelectedItem="{Binding SelectedStatus, Converter={StaticResource EnumToStringConverter}}" /> 

संपादित करें: आप एक अधिक जटिल मूल्य कनवर्टर और मार्कअप विस्तार कर सकते हैं। EnumToStringConverter अनुवादित तार प्राप्त करने के लिए DescriptionAttribute का उपयोग कर सकते हैं। और EnumerateExtensionTypeConverter.GetStandardValues() और एक कनवर्टर का उपयोग कर सकते हैं। यह निर्दिष्ट प्रकार के मानक मान प्राप्त करने की अनुमति देता है (न केवल Enum एस) और कनवर्टर के आधार पर उन्हें तारों या किसी अन्य में परिवर्तित करें।

उदाहरण:

<ComboBox ItemsSource="{local:Enumerate {x:Type sg:CultureInfo}, Converter={StaticResource CultureToNameConverter}}" 
      SelectedItem="{Binding SelectedCulture, Converter={StaticResource CultureToNameConverter}}" /> 

संपादित करें: अधिक जटिल समाधान ऊपर वर्णित GitHub पर प्रकाशित हुआ है अब।

+0

यह दृश्य स्तर पर एक अच्छा समाधान है – Tseng

2

आप बॉक्स से बाहर, नहीं कर सकता।

लेकिन आप ObservableList<KeyValuePair<StatusEnum, string>> संपत्ति बना सकते हैं और इसे अपने enum/localized text से भर सकते हैं और फिर इसे अपने ComboBox पर बाध्य कर सकते हैं।

स्ट्रिंग खुद के लिए के रूप में:

var localizedText = (string)Application.Current.FindResource("YourEnumStringName"); 

Enum.GetName/Enum.GetNames तरीकों के साथ Enum स्ट्रिंग प्रतिनिधित्व हो रही है।

1

आप enum के लिए एक विशेषता का उपयोग और enum के लिए एक विस्तार विधि लिख कर सकते हैं। नीचे दिए गए कोड का संदर्भ लें।

<ComboBox Width="200" Height="25" ItemsSource="{Binding ComboSource}" 
      DisplayMemberPath="Value" 
      SelectedValuePath="Key"/> 


public class MainViewModel 
{ 
    public List<KeyValuePair<Status, string>> ComboSource { get; set; } 

    public MainViewModel() 
    { 
     ComboSource = new List<KeyValuePair<Status, string>>(); 
     Status st=Status.Open; 
     ComboSource = re.GetValuesForComboBox<Status>(); 
    } 
} 

public enum Status 
{ 
    [Description("Open")] 
    Open, 
    [Description("Closed")] 
    Closed, 
    [Description("InProgress")] 
    InProgress 
} 

public static class ExtensionMethods 
    { 
     public static List<KeyValuePair<T, string>> GetValuesForComboBox<T>(this Enum theEnum) 
     { 
      List<KeyValuePair<T, string>> _comboBoxItemSource = null; 
      if (_comboBoxItemSource == null) 
      { 
       _comboBoxItemSource = new List<KeyValuePair<T, string>>(); 
       foreach (T level in Enum.GetValues(typeof(T))) 
       { 
        string Description = string.Empty; 
        FieldInfo fieldInfo = level.GetType().GetField(level.ToString()); 
        DescriptionAttribute[] attributes = (DescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(DescriptionAttribute), false); 
        if (attributes != null && attributes.Length > 0) 
        { 
         Description = GetDataFromResourceFile(attributes.FirstOrDefault().Description); 
        } 
        KeyValuePair<T, string> TypeKeyValue = new KeyValuePair<T, string>(level, Description); 
        _comboBoxItemSource.Add(TypeKeyValue); 
       } 
      } 
      return _comboBoxItemSource; 
     } 

     public static string GetDataFromResourceFile(string key) 
     { 
      //Do you logic to get from resource file based on key for a language. 
     } 
    } 

मैं पहले से ही इतना Is it possible to databind to a Enum, and show user-friendly values?

संबंधित मुद्दे