Как я могу заставить Html.CheckBoxFor () работать на строковом поле? - PullRequest
12 голосов
/ 25 августа 2011

Я использую ASP.NET MVC3 с Razor и C #. Я делаю сборщик форм, поэтому у меня есть модель, которая имеет коллекцию следующего объекта:

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 к логическому выражению в лямбда-выражении для CheckBoxFor (), но это вызвало ошибку. Я бы просто создал вход для флажка, но CheckBoxFor (), кажется, выполняет две вещи, которые я не могу воспроизвести:

  1. Создает скрытый ввод, который каким-то образом заполняется флажком. Похоже, это то, что связывает модель.
  2. Создает имя из объекта, чтобы связыватель модели мог получить значение в нужном свойстве.

Кто-нибудь знает способ использования CheckBoxFor () для строки или способ репликации ее функций вручную, чтобы я мог заставить это работать?

Ответы [ 4 ]

12 голосов
/ 26 августа 2011

Вы также можете добавить свойство для вашей модели представления:

    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, если вы хотите избежать исключений.

11 голосов
/ 26 августа 2011

Один из способов - создать собственный метод расширения 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 (e.Value - строка)

@Html.CheckBoxStringFor(e => e.Value)
4 голосов
/ 20 января 2015

Используйте флажок, этот простой способ отлично работает

@Html.CheckBox("IsActive", Model.MyString == "Y" ? true : false)
0 голосов
/ 16 августа 2012

У меня тоже была эта проблема, но я не смог изменить модель представления.Пробовал решение mdm20s, но, как я и подозревал, оно не работает со свойствами коллекции (оно не добавляет индексы к именам и идентификаторам, как нативные html-помощники).Чтобы преодолеть это, вы можете использовать Html.CheckBox.Он добавляет правильные индексы, и вы можете передать значение флажка самостоятельно.

Если вы действительно хотите использовать выражение, вы всегда можете написать обертку, похожую на mdm20s, но заменить все после TryParse на return Html.CheckBox("propertyName", isChecked).Очевидно, вам также нужно добавить using System.Web.Mvc.Html.

...