2012-03-10 15 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 
}; 

のように見えるように列挙型の値を持つコンボボックスを移入するために選択リストを使用していますか?

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ヘルパー::

答えて

12

カスタム属性書くことができ

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

CONTR oller:

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

ビュー:

@model MyViewModel 

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

最後に、あなたが必要な鍵(SaleRentSaleOrRent)が含まれていますMessages.resxファイルを作成する必要があります。また、ローカライズしたい場合は、別のカルチャに同じキーでMessages.xx-XX.resxを定義し、現在のスレッドカルチャをスワップするだけです。

関連する問題