2012-03-10 62 views
3

在我的MVC3應用程序中。我使用的選擇列表來填充組合框,像這樣SelectList中的本地化枚舉字符串

<div class="editor-field"> 
    @Html.DropDownListFor(x => x.AdType, new SelectList(Enum.GetValues(typeof(MyDomain.Property.AdTypeEnum))), " ", new { @class = "dxeButtonEdit_Glass" }) 
</div> 

MyDomain.Property枚舉值看起來像這樣

public enum AdTypeEnum 
{ 
    Sale = 1,   
    Rent = 2,   
    SaleOrRent = 3 
}; 

我如何使用我的本地化字符串本地化這些枚舉?

回答

12

你可以寫一個自定義屬性:

public class LocalizedNameAttribute: Attribute 
{ 
    private readonly Type _resourceType; 
    private readonly string _resourceKey; 

    public LocalizedNameAttribute(string resourceKey, Type resourceType) 
    { 
     _resourceType = resourceType; 
     _resourceKey = resourceKey; 
     DisplayName = (string)_resourceType 
      .GetProperty(_resourceKey, BindingFlags.Static | BindingFlags.NonPublic | BindingFlags.Public) 
      .GetValue(null, null); 
    } 

    public string DisplayName { get; private set; } 
} 

和一個自定義DropDownListForEnum幫手:

public static class DropDownListExtensions 
{ 
    public static IHtmlString DropDownListForEnum<TModel, TProperty>(
     this HtmlHelper<TModel> htmlHelper, 
     Expression<Func<TModel, TProperty>> expression, 
     string optionLabel, 
     object htmlAttributes 
    ) 
    { 
     if (!typeof(TProperty).IsEnum) 
     { 
      throw new Exception("This helper can be used only with enum types"); 
     } 

     var enumType = typeof(TProperty); 
     var fields = enumType.GetFields(
      BindingFlags.Static | BindingFlags.GetField | BindingFlags.Public 
     ); 
     var values = Enum.GetValues(enumType).OfType<TProperty>(); 
     var items = 
      from value in values 
      from field in fields 
      let descriptionAttribute = field 
       .GetCustomAttributes(
        typeof(LocalizedNameAttribute), true 
       ) 
       .OfType<LocalizedNameAttribute>() 
       .FirstOrDefault() 
      let displayName = (descriptionAttribute != null) 
       ? descriptionAttribute.DisplayName 
       : value.ToString() 
      where value.ToString() == field.Name 
      select new { Id = value, Name = displayName }; 

     var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); 
     var enumObj = metadata; 
     var selectList = new SelectList(items, "Id", "Name", metadata.Model); 
     return htmlHelper.DropDownListFor(expression, selectList, optionLabel, htmlAttributes); 
    } 
} 

然後很容易:

型號:

public enum AdTypeEnum 
{ 
    [LocalizedName("Sale", typeof(Messages))] 
    Sale = 1, 
    [LocalizedName("Rent", typeof(Messages))] 
    Rent = 2, 
    [LocalizedName("SaleOrRent", typeof(Messages))] 
    SaleOrRent = 3 
} 

public class MyViewModel 
{ 
    public AdTypeEnum AdType { get; set; } 
} 

對照奧勒:

public class HomeController : Controller 
{ 
    public ActionResult Index() 
    { 
     return View(new MyViewModel 
     { 
      AdType = AdTypeEnum.SaleOrRent 
     }); 
    } 
} 

查看:

@model MyViewModel 

@Html.DropDownListForEnum(
    x => x.AdType, 
    " ", 
    new { @class = "foo" } 
) 

最後,你應該創建一個Messages.resx文件,該文件將包含必需的密鑰(SaleRentSaleOrRent)。如果您想本地化,只需使用相同的密鑰爲不同的文化定義Messages.xx-XX.resx並交換當前的線索文化。