2015-04-15 12 views
12

Tôi có một danh sách ComboBox một Enum.Enum trong WPF ComboxBox với tên địa phương

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

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

Tôi muốn hiển thị tên bản địa hoá cho các giá trị enum bằng tiếng Anh

Open 
Closed 
In Progress 

mà còn ở Đức (và các ngôn ngữ khác trong tương lai)

Offen 
Geschlossen 
In Arbeit 

Trong ViewModel của tôi sử dụng

public IEnumerable<StatusEnum> StatusList 
{ 
    get 
    { 
     return Enum.GetValues(typeof(StatusEnum)).Cast<StatusEnum>(); 
    } 
} 

chỉ cho tôi biết tên của enum trong mã chứ không phải tên được dịch.

Tôi có nội địa hóa chung tại chỗ và có thể truy cập chúng bằng ví dụ:

Resources.Strings.InProgress 

mà được tôi dịch cho ngôn ngữ hiện hành.

Làm cách nào để tự động liên kết bản địa hóa?

+0

Bạn đã có một hệ thống bản địa hóa của một số sắp xếp chưa? Nếu có, chi tiết? Hay chúng ta chỉ cần đưa bạn đến một phương thức 'chuỗi GetValue (trạng thái StatusEnum)' và cho phép bạn bản địa hoá từ đó? –

+0

Tôi đã bản địa hóa tại chỗ. Tôi chỉ cần tìm ra nó cho enums Binding, –

Trả lời

14

Đây là một ví dụ về sự đơn giản Enum để chuyển đổi chuỗi dịch.

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"); 
    } 
} 

Ngoài ra bạn cần một MarkupExtension mà sẽ cung cấp giá trị:

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

Cách sử dụng:

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

EDIT: Bạn có thể làm cho một phần mở rộng chuyển đổi giá trị và đánh dấu phức tạp hơn. Các EnumToStringConverter có thể sử dụng DescriptionAttribute 's để có được các chuỗi dịch. Và EnumerateExtension có thể sử dụng TypeConverter.GetStandardValues() và bộ chuyển đổi. Điều này cho phép để có được các giá trị tiêu chuẩn của loại quy định (không chỉ Enum s) và chuyển đổi chúng thành chuỗi hoặc cái gì khác tùy thuộc vào bộ chuyển đổi.

Ví dụ:

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

EDIT: Các giải pháp phức tạp hơn mô tả ở trên được công bố trên GitHub bây giờ.

+0

Đó là một giải pháp tuyệt vời trên cấp độ Xem – Tseng

2

Bạn không thể thoát ra khỏi hộp.

Nhưng bạn có thể tạo thuộc tính ObservableList<KeyValuePair<StatusEnum, string>> và điền nó bằng văn bản enum/bản địa hóa của bạn và sau đó liên kết nó với ComboBox của bạn.

Đối với chuỗi chính nó:

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

Bắt chuỗi đại diện Enum với Enum.GetName/Enum.GetNames phương pháp.

1

Bạn có thể thực hiện bằng cách sử dụng Thuộc tính cho enum và viết phương thức mở rộng cho enum. Tham khảo mã dưới đây.

<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. 
     } 
    } 

Tôi đã đăng tải một điều tương tự trong SO Is it possible to databind to a Enum, and show user-friendly values?

Các vấn đề liên quan