2012-06-26 6 views
12

Morgen alle.MVC 4, Checkbox-Liste und ich

Ich kann sehen, das wurde an anderer Stelle diskutiert, aber fragte sich, ob etwas geändert oder Dinge in MVC 4 für Dummköpfe wie mich einfacher gemacht hatte ?!

Szenario

Ich habe folgendes, bearbeitet Modell:

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; } 
} 

Mit dem folgenden Standard Ansicht erstellen:

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

Das gibt mir, aus von der Box, ein schönes Drop Dow n Liste a la Scott Gu's blog

Nun meine eigentliche Frage ist dies - wie kann ich effektiv diese Dropdown-Box, was effektiv eine Multi-Auswahl, Checkbox-Liste zu konvertieren?

Wieder entschuldigte ich mich dafür, über den Boden zu gehen, aber ich habe gerade das Wasser getestet, um zu sehen, ob irgendwelche Aktualisierungen stattgefunden haben.

Bitte beachten Sie, erstes MVC-Projekt so sanft gehen, ich fühle mich sehr dick wieder: '(

Antwort

19

Richtig ok, ich habe es sortiert - hurra! Wie Sie aus den Kommentaren sehen können, gab es ein paar Probleme, die aufkommen, aber unterhalb der Komplettlösung bitte DOES Arbeit finden, die: D

Modell

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

Erweiterung (in einem Ordner im Stammverzeichnis des Projekts)

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()); 
    } 

Erweiterung in Web-Config der

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

Ansicht

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

Aufrufe registrierte Was mir eine schöne Liste von Kontrollkästchen gibt. Hurra!

Danke Danke für Ihre Hilfe, ich habe dies als die Antwort aber +50 für Ihre Zeit und Mühe markiert.

+0

Wirklich hilfreich, aber es wäre noch besser, wenn die Validierung enthalten wäre. Momentan erhalten alle meine Textfelder einen roten Rahmen, wenn ein Validierungsproblem vorliegt. Haben Sie eine Idee, wie Sie diese Funktion einbeziehen können? – Owen

2

keine Änderungen aufgetreten in ASP.NET MVC 4 RC in diesem Aspekte und sind unwahrscheinlich, wenn es RTM Hits so.

Aber man kann immer noch implement a custom helper das erreichen. Und man kann auch diese Helfer verbessern, dass sie anstelle einer Zeichenfolge zu haben, um stark typisierte Version.

Und wenn Sie einen Lambda-Ausdruck als erstes Argument Verwenden Sie hier keine Enums another example.

+0

Dank Darin geben - mit der Erweiterung exmaple, soll ich nur noch hinzufügen das als irgendwo in meinem Projekt oder speziell in den Ansichten? (Entschuldigung für die blöde Frage, siehe frühere Fußnote "erstes MVC-Projekt") –

+0

Sie könnten einen 'Extensions'-Ordner erstellen und eine' HtmlExtensions.cs'-Klasse darin haben, in der Sie sie deklarieren. –

+0

, die Sinn machen würde: D –

1

Wenn Sie ausgewählten Wert auf mehr bereits (Parameter # 4)

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

ändern Sie den Helfer zu

 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()); 
    }