Вопрос по drop-down-menu, checkbox, razor, asp.net-mvc, asp.net-mvc-4 – MVC 4, флажок список и я

12

Всем утро.

Я могу видеть, что это обсуждалось в другом месте, но мне было интересно, если что-нибудь изменилось или все стало проще в MVC 4 для простаков вроде меня ?!

Scenario

У меня есть следующее, отредактировано,model:

public class CorporateDetails
{

    public Guid? Id { get; set; }

    [Key]
    public int CorporateDetailId { get; set; }

    public int? EmsId { get; set; }
    public string EmsName { get; set; }

    public virtual EmsType EmsType { get; set; }
}

public class EmsType
{
    [Key]
    public int? EmsId { get; set; }
    public string EmsName { get; set; }

    public virtual ICollection<EmsType> EmsTypes { get; set; }
}

Со следующим стандартом создатьview:

 <fieldset>
    <legend>CorporateDetails</legend>



    <div class="editor-label">
        @Html.LabelFor(model => model.EmsId, "EmsType")
    </div>
    <div class="editor-field">
        @Html.DropDownList("EmsId", String.Empty)
        @Html.ValidationMessageFor(model => model.EmsId)
    </div>
    <div class="editor-label">
        @Html.LabelFor(model => model.EmsName)
    </div>
    <div class="editor-field">
        @Html.EditorFor(model => model.EmsName)
        @Html.ValidationMessageFor(model => model.EmsName)
    </div>

    <p>
        <input type="submit" value="Create" />
    </p>
</fieldset>

Это дает мне из коробки красивый выпадающий список а-ляБлог Скотта Гу

Теперь мой реальный вопрос заключается в следующем: как я могу эффективно преобразовать этот выпадающий список в список с несколькими флажками?

Опять же, извиняюсь за то, что перешел через протоптанную землю, но я просто проверял воду, чтобы увидеть, произошли ли какие-либо обновления.

Пожалуйста, обратите внимание, первый проект MVC, так что будьте осторожны, я снова чувствую себя очень толстым: "

Ваш Ответ

4   ответа
5

Хорошее решение -

Просто для справки других - у меня, как и у вас, возникла необходимость в чекбокс-листе - я использовал это здесь:

http://www.codeproject.com/Articles/292050/CheckBoxList-For-a-missing-MVC-extension

Это прекрасно работает ... очень хорошо написано - надеюсь, это может кому-то помочь.

Loren

2

В ASP.NET MVC 4 RC не произошло никаких изменений в этом аспекте, и они вряд ли произойдут при попадании в RTM.

Но ты все еще могреализовать пользовательский помощник чтобы достичь этого. И вы могли бы даже улучшить этот помощник, чтобы он использовал лямбда-выражение в качестве первого аргумента вместо строки, чтобы иметь строго типизированную версию.

И если вы не используете перечисления здесьдругой пример.

Извините, Дарин, снова я: "(Я" реализовал это, но получил неприятную ошибку: CS1973: "System.Web.Mvc.HtmlHelper & lt; Models.CorporateDetails & gt; & gt; & gt; & gt; & gt; & gt; & gt; & gt; & gt; & gt; & gt; & gt; & gt; & gt; & gt; & gam; У меня есть метод расширения с таким именем. Методы расширения не могут быть отправлены динамически. Рассмотрим приведение динамических аргументов или вызов метода расширения без синтаксиса метода расширения. Я пытался добавить @using MvcHtmlHelpers; (мой помощник) в само представление, но получил застрял. Есть идеи? Ricardo Deano
Вы могли бы создатьExtensions папка и естьHtmlExtensions.cs класс внутри, в котором вы их объявите.
Как ты это называешь? Я полагаю, вы используетеViewBag или что-то?
Спасибо, Дарин, с расширением exmaple. Должен ли я добавить это как-нибудь в моем проекте или, в частности, в представлениях? (Извинения за глупый вопрос, см. Ранее «первый проект MVC» сноска) Ricardo Deano
Это имело бы смысл: D Ricardo Deano
1

Если вы передаете выбранное значение в MultiSelected (параметр # 4)

ViewBag.VfonctionIds = new MultiSelectList(db.tbIntervenantFonctionTypes, "intervenantFonctionType_id", "Nom", fonctionSelected);  

Измените Помощника на

        public static MvcHtmlString CheckBoxListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty[]>> expression, MultiSelectList multiSelectList, object htmlAttributes = null)
    {
        //Derive property name for checkbox name
        MemberExpression body = expression.Body as MemberExpression;
        string propertyName = body.Member.Name;

        //Create div
        TagBuilder divTag = new TagBuilder("div");
        divTag.MergeAttributes(new RouteValueDictionary(htmlAttributes), true);

        //Add checkboxes
        foreach (SelectListItem item in multiSelectList)
        {
            divTag.InnerHtml += String.Format("<div><input type=\"checkbox\" name=\"{0}\" id=\"{0}_{1}\" " +
                                                "value=\"{1}\" {2} /><label for=\"{0}_{1}\">{3}</label></div>",
                                                propertyName,
                                                item.Value,
                                                (item.Selected) ? "checked=\"checked\"" : "",                                                    
                                                item.Text);
        }

        return MvcHtmlString.Create(divTag.ToString());
    }
19

Хорошо, у меня все отсортировано - ура! Как вы можете видеть из комментариев, возникло несколько проблем, но ниже вы найдете полное решение, которое РАБОТАЕТ: D

Model

 public class CorporateDetails
    {

        public Guid? Id { get; set; }

        [Key]
        public int CorporateDetailId { get; set; }

        public int[] EmsId { get; set; }

        }

    public class EmsType
    {
        [Key]
        public int EmsId { get; set; }
        public string EmsName { get; set; }

        public virtual ICollection<EmsType> EmsTypes { get; set; }
    }

Controller

 public ActionResult Create()
    {
        CorporateDetails corporatedetails = new CorporateDetails();
        ViewBag.EmsId = new MultiSelectList(db.EmsTypes, "EmsId", "EmsName");
        return View(corporatedetails);
    }

Extension (помещается в папку в корне проекта)

 public static MvcHtmlString CheckBoxListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty[]>> expression, MultiSelectList multiSelectList, object htmlAttributes = null)
    {
        //Derive property name for checkbox name
        MemberExpression body = expression.Body as MemberExpression;
        string propertyName = body.Member.Name;

        //Get currently select values from the ViewData model
        TProperty[] list = expression.Compile().Invoke(htmlHelper.ViewData.Model);

        //Convert selected value list to a List<string> for easy manipulation
        List<string> selectedValues = new List<string>();

        if (list != null)
        {
            selectedValues = new List<TProperty>(list).ConvertAll<string>(delegate(TProperty i) { return i.ToString(); });
        }

        //Create div
        TagBuilder divTag = new TagBuilder("div");
        divTag.MergeAttributes(new RouteValueDictionary(htmlAttributes), true);

        //Add checkboxes
        foreach (SelectListItem item in multiSelectList)
        {
            divTag.InnerHtml += String.Format("<div><input type=\"checkbox\" name=\"{0}\" id=\"{0}_{1}\" " +
                                                "value=\"{1}\" {2} /><label for=\"{0}_{1}\">{3}</label></div>",
                                                propertyName,
                                                item.Value,
                                                selectedValues.Contains(item.Value) ? "checked=\"checked\"" : "",
                                                item.Text);
        }

        return MvcHtmlString.Create(divTag.ToString());
    }

Extension registered in web config of the Views

 <pages pageBaseType="System.Web.Mvc.WebViewPage">
  <namespaces>
    <add namespace="System.Web.Mvc" />
    <add namespace="System.Web.Mvc.Ajax" />
    <add namespace="System.Web.Mvc.Html" />
    <add namespace="System.Web.Optimization"/>
    <add namespace="System.Web.Routing" />
    <add namespace="MyProject.Extensions" />
  </namespaces>
</pages>

View

@model Valpak.Websites.HealthChecker.Models.CorporateDetails
@{
    ViewBag.Title = "Create";
}
<h2>Create</h2>
@using (Html.BeginForm())
{
    @Html.ValidationSummary(true)

    <fieldset>
        <legend>CorporateDetails</legend>

           <div class="editor-label">
           @Html.CheckBoxListFor(model => model.EmsId, (MultiSelectList) ViewBag.EmsId)
          </div>          
        <p>
            <input type="submit" value="Create" />
        </p>
    </fieldset>
}
<div>
    @Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
}

Что дает мне прекрасный список флажков. Ура!

Спасибо, Дарин, за помощь, я пометил это как ответ, но +50 за ваше время и усилия.

Действительно полезно, но было бы еще лучше, если бы проверка была включена. В настоящее время все мои текстовые поля имеют красную рамку, если есть проблема с проверкой, есть ли у вас идеи, как включить эту функцию?

Похожие вопросы