Как я могу заставить Html.CheckBoxFor() работать в поле строки?
Я использую ASP.NET MVC3 с Razor и С#. Я создаю компоновщик форм, поэтому у меня есть модель, у которой есть коллекция следующего объекта:
public class MyFormField
{
public string Name { get; set; }
public string Value { get; set; }
public MyFormType Type { get; set; }
}
MyFormType - это просто перечисление, которое сообщает мне, является ли поле формы флажком или текстовым полем, или загрузка файла, или что-то еще. Мой шаблон редактора выглядит примерно так (см. Комментарий):
~/Views/EditorTemplates/MyFormField.cshtml
@model MyFormField
@{
switch (Model.Type)
{
case MyFormType.Textbox:
@Html.TextBoxFor(m => m.Value)
case MyFormType.Checkbox:
@Html.CheckBoxFor(m => m.Value) // This does not work!
}
}
Я попробовал кастинг/преобразование m.Value
в bool в выражении лямбда для CheckBoxFor(), но это заставило ошибку. Я просто вручную создаю флажок, но CheckBoxFor(), похоже, выполняет две вещи, которые, как я могу, не реплицируются:
- Создает скрытый ввод, который каким-то образом заполняется флажком. Похоже, это то, что подбирает модельное связующее.
- Генерирует имя формы для объекта, чтобы привязка к модели вносила значение в правильное свойство.
Кто-нибудь знает способ использования CheckBoxFor() в строке или способ репликации ее функций вручную, чтобы я мог сделать эту работу?
Ответы
Ответ 1
Вы также можете добавить свойство на свою модель просмотра:
public class MyFormField
{
public string Name { get; set; }
public string Value { get; set; }
public bool CheckBoxValue
{
get { return Boolean.Parse(Value); }
}
public MyFormType Type { get; set; }
}
Ваше мнение будет выглядеть примерно так:
@model MyFormField
@{
switch (Model.Type)
{
case MyFormType.Textbox:
@Html.TextBoxFor(m => m.Value)
case MyFormType.Checkbox:
@Html.CheckBoxFor(m => m.CheckBoxValue) // This does work!
}
}
Используйте Boolean.TryParse, если вы хотите избежать исключений.
Ответ 2
Один из способов - создать собственный метод расширения htmlhelper.
public static MvcHtmlString CheckBoxStringFor<TModel>(this HtmlHelper<TModel> html, Expression<Func<TModel, string>> expression)
{
// get the name of the property
string[] propertyNameParts = expression.Body.ToString().Split('.');
string propertyName = propertyNameParts.Last();
// get the value of the property
Func<TModel, string> compiled = expression.Compile();
string booleanStr = compiled(html.ViewData.Model);
// convert it to a boolean
bool isChecked = false;
Boolean.TryParse(booleanStr, out isChecked);
TagBuilder checkbox = new TagBuilder("input");
checkbox.MergeAttribute("id", propertyName);
checkbox.MergeAttribute("name", propertyName);
checkbox.MergeAttribute("type", "checkbox");
checkbox.MergeAttribute("value", "true");
if (isChecked)
checkbox.MergeAttribute("checked", "checked");
TagBuilder hidden = new TagBuilder("input");
hidden.MergeAttribute("name", propertyName);
hidden.MergeAttribute("type", "hidden");
hidden.MergeAttribute("value", "false");
return MvcHtmlString.Create(checkbox.ToString(TagRenderMode.SelfClosing) + hidden.ToString(TagRenderMode.SelfClosing));
}
Использование такое же, как и CheckBoxFor helper (e.Value - строка)
@Html.CheckBoxStringFor(e => e.Value)
Ответ 3
Используйте флажок, этот простой способ отлично работает
@Html.CheckBox("IsActive", Model.MyString == "Y" ? true : false)
Ответ 4
У меня тоже была эта проблема, но мне не удалось изменить модель представления. Пробовал решение mdm20s, но, как я подозревал, он не работает над свойствами коллекции (он не добавляет индексы к именам и идентификаторам, например, встроенным html-помощникам). Чтобы преодолеть это, вы можете вместо этого использовать Html.CheckBox. Он добавляет правильные индексы, и вы можете передать значение флажка самостоятельно.
Если вы действительно хотите использовать выражение, вы всегда можете написать оболочку, похожую на mdm20s, но заменить все после TryParse
return Html.CheckBox("propertyName", isChecked)
. Очевидно, вам также нужно добавить using System.Web.Mvc.Html
.