asp.net-mvc MVC 4,复选框列表和我

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11204464/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 02:03:18  来源:igfitidea点击:

MVC 4, Checkbox list and me

asp.net-mvcrazordrop-down-menucheckboxasp.net-mvc-4

提问by Ricardo Deano

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?!

我可以看到这已经在其他地方讨论过,但想知道 MVC 4 中是否有什么改变或事情让像我这样的傻瓜变得更简单了?!

Scenario

设想

I have the following,edited, 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; }
}

With the following standard create 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>

This gives me, out of the box, a beautiful drop down list a la Scott Gu's blog

这给了我一个开箱即用的漂亮下拉列表,如Scott Gu 的博客

Now my real question is this - how can I effectively convert this drop down box to what will effectively be a multi select,checkbox list?

现在我真正的问题是 - 如何有效地将此下拉框转换为有效的多选复选框列表?

Again, apologies for going over trodden ground but I was just testing the water to see if any updates have occurred.

再次,为越过人迹而道歉,但我只是在试水,看看是否发生了任何更新。

Please note, first MVC project so go gently, I'm feeling very thick again :'(

请注意,第一个MVC项目,所以轻轻地,我又感觉很厚:'(

回答by Ricardo Deano

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

好的,我已经整理好了 - 万岁!正如您从评论中看到的那样,出现了一些问题,但请在下面找到有效的完整解决方案: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

在视图的 web 配置中注册的扩展

 <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.

感谢 Darin 的帮助,我已将此标记为答案,但为您的时间和精力 +50。

回答by 99823

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

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

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

它工作得很好......写得很好 - 希望这可以帮助某人。

Loren

罗兰

回答by Darin Dimitrov

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

ASP.NET MVC 4 RC 在这方面没有发生任何变化,并且在它遇到 RTM 时不太可能发生。

But you could still implement a custom helperto 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.

但是您仍然可以实现自定义帮助程序来实现这一目标。你甚至可以改进这个助手,以便它接受一个 lambda 表达式作为第一个参数而不是一个字符串,以便具有强类型版本。

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

如果你没有使用枚举,这里是另一个例子

回答by Pascal Carmoni

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

如果您将选定的值传递给 MultiSelected(参数 #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());
    }