Azureはじめました

Windows Azureで業務システムを組んでみる日記

Razorで列挙型のプロパティにRadioボタンを割り当てる

EFのエンティティに列挙型プロパティを設定したとき、Scafoldingでは単純にそのプロパティが無視されるだけになるので、ここにRadioButtonを割り当てることはできんもんか。

public enum UserState{
  Active,
  Suspend,
  Inactive,
  Banned,
}

public class User {
  public int Id {get;set;}

  [Required]
  public string Name {get;set;}
  
  [Required]
  public UserState Status {get;set;}
}

こんなの。

安心のStackoverflow

やっぱあった。
asp.net mvc - pass enum to html.radiobuttonfor MVC3 - Stack Overflow

public static class HtmlExtensions
{
    public static MvcHtmlString RadioButtonForEnum<TModel, TProperty>(
        this HtmlHelper<TModel> htmlHelper, 
        Expression<Func<TModel, TProperty>> expression
    )
    {
        var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
        var names = Enum.GetNames(metaData.ModelType);
        var sb = new StringBuilder();
        foreach (var name in names)
        {
            var id = string.Format(
                "{0}_{1}_{2}", 
                htmlHelper.ViewData.TemplateInfo.HtmlFieldPrefix, 
                metaData.PropertyName, 
                name
            );

            var radio = htmlHelper.RadioButtonFor(expression, name, new { id = id }).ToHtmlString();
            sb.AppendFormat(
                "<label for=\"{0}\">{1}</label> {2}", 
                id, 
                HttpUtility.HtmlEncode(name), 
                radio
            );
        }
        return MvcHtmlString.Create(sb.ToString());
    }
}

Razorの@Html(HtmlHelper?)を拡張して列挙型をRadioButtonのタグを生成するのか。

このクラスをプロジェクトに作成してViewからは

@model User
@using (Html.BeginForm())
{
    @Html.RadioButtonForEnum(user => user.Status)
    <input type="submit" value="OK" />
}

みたいな感じ。

ラベルの後にラジオボタンが出るのはRadioButtonForEnumの sb.AppendFormat()してるとこを弄ってデザインはスタイルシートでやる感じか。