Ответ 1
Хорошо, сделаем некоторые исследования. Прежде всего, вам не нужен уникальный идентификатор для переключения флажка/радио, щелкнув метку. На самом деле вам вообще не нужен идентификатор! Все, что вам нужно сделать, это обернуть ваш вход в тег <label>
:
<label>
<input type="radio" name="radio" value="1" /> Radio 1
</label>
До сих пор так хорошо, ASP.NET MVC предоставляет вам возможность кодировать собственные html-помощники, писать одну в поле модели Enum
!
Представьте, у нас есть модель регистрации:
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
к нашей модели (желание, С# имеет модификатор доступа 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>"); //we want it to look cool, dont' we?
foreach (var value in Enum.GetValues(typeof(TEnum)))
{
var radio = htmlHelper.RadioButtonFor(expression, value).ToHtmlString(); //you can generage any id and pass it to helper, or use a tagbuilder
sb.AppendFormat(
"<li><label>{0} {1}</label></li>",
radio,
((Enum)value).GetEnumName() //instead of it you can grab e.g. Display/Description attribute value or w/e else
);
}
sb.Append("</ul");
return MvcHtmlString.Create(sb.ToString());
}
и использование этого будет выглядеть так:
@Html.RadioButtonsListForEnum(m => m.Gender)
Так красиво, не так ли? Разумеется, вы можете добавить хеллу много настроек, например рендеринг радиообъектов с уникальными идентификаторами mvc-стиля, все виды атрибутов html и т.д., Но это всего лишь образец, ударный удар на правильный путь.
Далее, мы также хотим отобразить checkboxlist!
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)
Btw, он имеет значение только для перечислений, помеченных атрибутом Flags
, и, конечно, у вас возникнут проблемы с привязкой к модели - для этого требуется специальное связующее. Но это еще один вопрос, и я надеюсь, что Jon Skeet может ответить на него:)