MVC 4, Checkbox list and me

后端 未结 4 2132
青春惊慌失措
青春惊慌失措 2020-12-28 21:53

Morning all.

I can see this has been discussed elsewhere but was wondering if anything had change or things made simpler in MVC 4 for simpletons like me?!

相关标签:
4条回答
  • 2020-12-28 22:05

    Nice solution -

    Just for others reference - I, like you, had run into a need for a checkboxlist - I have been using this here:

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

    It works great... very well written - hope this can help someone.

    Loren

    0 讨论(0)
  • 2020-12-28 22:07

    Right ok, I have got it sorted - hurrah! As you can see from the comments, there were a few issues that came up but please find below the complete solution which DOES work :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 (placed in a folder in the root of the project)

     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")
    }
    

    Which gives me a lovely list of check boxes. Hurrah!

    Thanks Darin for your help, I've marked this as the answer but +50 for your time and effort.

    0 讨论(0)
  • 2020-12-28 22:13

    If you pass selected value to MultiSelected (parameter #4)

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

    Change the Helper to

            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());
        }
    
    0 讨论(0)
  • 2020-12-28 22:16

    No changes occurred in ASP.NET MVC 4 RC in this aspect and are unlikely to occur when it hits RTM.

    But you could still implement a custom helper to achieve that. And you could even improve this helper so that it takes a lambda expression as first argument instead of a string in order to have strongly typed version.

    And if you are not using enums here's another example.

    0 讨论(0)
提交回复
热议问题