好的,让我们做一些研究。首先,您不需要唯一的id来通过单击标签切换复选框/单选按钮。实际上,您根本不需要id!您只需将输入包装在<label>
标记内即可:
<label>
<input type="radio" name="radio" value="1" /> Radio 1
</label>
到目前为止,ASP.NET MVC已经为您提供了编写自己的HTML Helper的能力,让我们为枚举(Enum)模型字段编写一个HTML Helper!
假设我们有一些注册模型:
public class RegisterViewModel
{
[Required]
[EmailAddress]
[Display(Name = "Email")]
public string Email { get; set; }
[Required]
[StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
public string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
public string ConfirmPassword { get; set; }
}
天哪!我刚刚复制粘贴了教程模型 o_O。现在我们想要获取用户的性别,所以我们添加一个 Gender
枚举:
public enum Gender
{
Iamparanoic = 0,
Male = 1,
Female = 2,
}
我们需要在模型中添加一个Gender
类型的Gender
字段(希望C#有一个Gender
访问修饰符!)
public Gender Gender { get; set; }
现在,是时候运用一些asp.net的魔法来编写我们的html辅助程序了:
public static MvcHtmlString RadioButtonsListForEnum<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression)
{
var sb = new StringBuilder();
sb.Append("<ul>");
foreach (var value in Enum.GetValues(typeof(TEnum)))
{
var radio = htmlHelper.RadioButtonFor(expression, value).ToHtmlString();
sb.AppendFormat(
"<li><label>{0} {1}</label></li>",
radio,
((Enum)value).GetEnumName()
);
}
sb.Append("</ul");
return MvcHtmlString.Create(sb.ToString());
}
使用的方式如下:
@Html.RadioButtonsListForEnum(m => m.Gender)
太漂亮了,不是吗?当然,您可以添加很多自定义内容,比如使用独特的mvc样式ID渲染单选按钮,各种HTML属性等等。但这只是一个示例,是正确路径的一记踢屁股。
接下来,我们还想呈现复选框列表!
public static MvcHtmlString CheckBoxListForEnum<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression, IDictionary<string, object> htmlAttributes = null)
{
var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
var enumValue = Convert.ToInt32(metadata.Model);
var sb = new StringBuilder();
foreach (var value in Enum.GetValues(typeof (TEnum)))
{
var val = Convert.ToInt32(value);
var checkbox = new TagBuilder("input");
checkbox.MergeAttribute("type", "checkbox");
checkbox.MergeAttribute("value", value.ToString());
checkbox.MergeAttribute("name", htmlHelper.NameFor(expression).ToString());
if ((enumValue & val) == val)
checkbox.MergeAttribute("checked", "checked");
if (htmlAttributes != null)
checkbox.MergeAttributes(htmlAttributes);
var label = new TagBuilder("label") { InnerHtml = checkbox + ((Enum)value).GetEnumName() };
sb.Append(label);
sb.Append("<br/>");
}
return new MvcHtmlString(sb.ToString());
}
再次,简单用法:
@Html.CheckBoxListForEnum(m => m.Gender)
顺便说一下,只有带有Flags
特性的枚举才有意义,并且在模型绑定时会遇到麻烦——需要自定义绑定器。但这是另一个问题,我希望Jon Skeet能回答它:)
RadioButtonFor
应该像DropDownListFor
一样有重载方法,我可以传递一个项目列表,每个项目都会生成可点击标签的单选按钮。 - th1rdey3