这是我最近创建的。如果您在非枚举上尝试它将不起作用,但可以满足我的枚举需求。我从不同的 DropDownList 助手(如 nikeaa 发布)中复制了一些片段。
#region RadioButtonList
public static MvcHtmlString RadioButtonListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, IDictionary<string, object> htmlAttributes = null) where TModel : class
{
ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
String field = ExpressionHelper.GetExpressionText(expression);
String fieldname = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldId(field);
var inputName = fieldname;
TProperty val = GetValue(htmlHelper, expression);
var divTag = new TagBuilder("div");
divTag.MergeAttribute("id", inputName);
divTag.MergeAttribute("class", "radio");
foreach (var item in Enum.GetValues(val.GetType()))
{
DisplayAttribute[] attr = (DisplayAttribute[])item.GetType().GetField(item.ToString()).GetCustomAttributes(typeof(DisplayAttribute), true);
if (attr == null || attr.Length == 0 || attr[0].Name != null)
{
string name = attr != null && attr.Length > 0 && !string.IsNullOrWhiteSpace(attr[0].Name) ? attr[0].Name : item.ToString();
var itemval = item;
var radioButtonTag = RadioButton(htmlHelper, inputName, new SelectListItem { Text = name, Value = itemval.ToString(), Selected = val.Equals(itemval) }, htmlAttributes);
divTag.InnerHtml += radioButtonTag;
}
}
return new MvcHtmlString(divTag.ToString());
}
public static string RadioButton(this HtmlHelper htmlHelper, string name, SelectListItem listItem,
IDictionary<string, object> htmlAttributes)
{
var inputIdSb = new StringBuilder();
inputIdSb.Append(name)
.Append("_")
.Append(listItem.Value);
var sb = new StringBuilder();
var builder = new TagBuilder("input");
if (listItem.Selected) builder.MergeAttribute("checked", "checked");
builder.MergeAttribute("type", "radio");
builder.MergeAttribute("value", listItem.Value);
builder.MergeAttribute("id", inputIdSb.ToString());
builder.MergeAttribute("name", name);
builder.MergeAttributes(htmlAttributes);
sb.Append(builder.ToString(TagRenderMode.SelfClosing));
sb.Append(RadioButtonLabel(inputIdSb.ToString(), listItem.Text, htmlAttributes));
sb.Append("<br>");
return sb.ToString();
}
public static string RadioButtonLabel(string inputId, string displayText,
IDictionary<string, object> htmlAttributes)
{
var labelBuilder = new TagBuilder("label");
labelBuilder.MergeAttribute("for", inputId);
labelBuilder.MergeAttributes(htmlAttributes);
labelBuilder.InnerHtml = displayText;
return labelBuilder.ToString(TagRenderMode.Normal);
}
public static TProperty GetValue<TModel, TProperty>(HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression) where TModel : class
{
TModel model = htmlHelper.ViewData.Model;
if (model == null)
{
return default(TProperty);
}
Func<TModel, TProperty> func = expression.Compile();
return func(model);
}
#endregion
我这样用
@Html.RadioButtonListFor(m => m.PlayFormat)
您可能需要更多代码来为更复杂的用途设置正确的元素名称。
如果枚举项具有 Display 属性,则显示名称。否则显示枚举项。如果显示名称为空,则该值不会显示为选项。在这个枚举中,不显示“None”,从枚举值显示“Singles”,“Men's Doubles”和所有其他的都有来自 [Display(Name="Men's Doubles")] 的文本
public enum PlayFormat
{
[Display(Name=null)]
None = 0,
Singles = 1,
[Display(Name = "Men's Doubles")]
MenDoubles = 2,
[Display(Name = "Women's Doubles")]
WomenDoubles = 3,
[Display(Name = "Mixed Doubles")]
MixedDoubles = 4,
[Display(Name = "Men's Group")]
MenGroup = 5,
[Display(Name = "Women's Group")]
WomenGroup = 6,
[Display(Name = "Mixed Group")]
MixedGroup = 7
}
页面看起来像这样(除了每个 - 是一个单选按钮)
- Singles
- Men's Doubles
- Women's Doubles
- Mixed Doubles
- Men's Group
- Women's Group
- Mixed Group