Ordnungsgemäße Verwendung von .net MVC Html.CheckBoxFor

77

Ich möchte nur die richtige Syntax für den Html.CheckBoxForHTML-Helfer in ASP.NET MVC wissen .

Ich versuche, das Kontrollkästchen zunächst mit einem ID-Wert zu aktivieren, damit ich im Controller darauf verweisen kann, ob es noch aktiviert ist oder nicht.

Wäre unten die richtige Syntax?

@foreach (var item in Model.Templates) 
{ 
    <td> 
        @Html.CheckBoxFor(model => true, item.TemplateId) 
        @Html.LabelFor(model => item.TemplateName)
    </td> 
}
sagesky36
quelle
ist ein itemTeil Ihres Modells oder was?
Robert Koritnik
Nein ... Hier ist der vollständige Code im HTML-Code @foreach (var item in Model.Templates) {<td> @ Html.CheckBoxFor (model => true, item.TemplateId) @ Html.LabelFor (model => item. TemplateName) </ td>}
sagesky36
Der Zweck der CheckBoxFor()(und CheckBox()) Methode besteht darin, an eine boolEigenschaft zu binden . Da TemplateIddies nicht zu sein scheint bool, verwenden Sie es nicht CheckBoxFor()- generieren Sie das HTML einfach manuell oder auf mvc-Weise - beziehen Sie sich auf diese Antwort

Antworten:

125

Das ist nicht die richtige Syntax

Der erste Parameter ist nicht der Wert des Kontrollkästchens, sondern die Ansicht, dass die Modellbindung für das Kontrollkästchen angezeigt wird.

@Html.CheckBoxFor(m => m.SomeBooleanProperty, new { @checked = "checked" });

Der erste Parameter muss eine boolesche Eigenschaft in Ihrem Modell identifizieren (es ist ein Ausdruck, keine anonyme Methode, die einen Wert zurückgibt), und die zweite Eigenschaft definiert alle zusätzlichen HTML-Elementattribute. Ich bin nicht 100% sicher, dass das obige Attribut zunächst Ihr Kontrollkästchen aktiviert, aber Sie können es versuchen. Aber Vorsicht. Auch wenn es möglicherweise funktioniert, können später Probleme auftreten, wenn Sie gültige Modelldaten laden und diese bestimmte Eigenschaft auf festgelegt ist false.

Der richtige Weg

Obwohl mein richtiger Vorschlag wäre, Ihrer Ansicht ein initialisiertes Modell mit dieser bestimmten booleschen Eigenschaft bereitzustellen, die auf initialisiert wurde true.

Eigenschaftstypen

Gemäß den MVC- HtmlHelperErweiterungsmethoden von Asp.net und der inneren Funktionsweise müssen Kontrollkästchen an boolesche Werte und nicht an Ganzzahlen gebunden werden , was Sie anscheinend tun möchten . In diesem Fall könnte ein verstecktes Feld das speichern id.

Andere Helfer

Es gibt natürlich auch andere Hilfsmethoden, mit denen Sie die Werte und das Verhalten von Kontrollkästchen flexibler gestalten können:

@Html.CheckBox("templateId", new { value = item.TemplateID, @checked = true });

Hinweis : checked Ist eine boolesche Eigenschaft eines HTML-Elements und kein Wertattribut. Dies bedeutet, dass Sie ihm einen beliebigen Wert zuweisen können. Die korrekte HTML-Syntax enthält keine Zuweisungen, es gibt jedoch keine Möglichkeit, ein anonymes C # -Objekt mit einer undefinierten Eigenschaft bereitzustellen, die als HTML-Elementeigenschaft gerendert wird.

Robert Koritnik
quelle
2
Vielen Dank, dass Sie es mir erklärt haben ... Scheint, dass dieser HTML-Helfer mir wirklich Kopfschmerzen bereitet hat. Ich habe Ihren Rat befolgt und die Eigenschaft isChecked auf TRUE initialisiert.
sagesky36
3
checkedsollte sein@checked
Kehlan Krumme
Nettes HOWTO auf CheckBox () und CheckBoxFor (): tutorialsteacher.com/mvc/htmlhelper-checkbox-checkboxfor
Wouter
Es gibt einen Haken.
Stellen
17

Standardmäßig generiert der folgende Code KEIN aktiviertes Kontrollkästchen, da Modelleigenschaften die HTML-Attribute überschreiben:

@Html.CheckBoxFor(m => m.SomeBooleanProperty, new { @checked = "checked" });

Stattdessen muss in Ihrer GET Action- Methode Folgendes ausgeführt werden:

model.SomeBooleanProperty = true;

Das oben Gesagte behält Ihre Auswahl bei (wenn Sie das Kontrollkästchen deaktivieren), auch wenn das Modell nicht gültig ist (dh beim Senden des Formulars tritt ein Fehler auf).

Der folgende Code generiert zwar ein aktiviertes Kontrollkästchen, behält jedoch nicht Ihre deaktivierten Antworten bei , sondern aktiviert das Kontrollkästchen jedes Mal bei Fehlern im Formular.

 @Html.CheckBox("SomeBooleanProperty", new { @checked = "checked" });

AKTUALISIEREN

//Get Method
   public ActionResult CreateUser(int id)
   {
        model.SomeBooleanProperty = true;         
   }

Der obige Code würde beim Start ein Häkchen erzeugen und Ihre Auswahl auch bei Formfehlern beibehalten.

T Gupta
quelle
Vielen Dank! Du hast mich gerettet! Ich habe immer wieder eine Nullreferenz auf meinem Bool erhalten, weil ich sie in meinem GET nicht initialisiert habe.
Floh
Das sah so aus, als würde es mich retten, aber ich kann die Teile nicht zusammenfügen. Wenn meine Seite geladen wird, werden die Kontrollkästchen entsprechend angezeigt. Wenn die Seite beim Post-Back ein serverseitiges ungültiges Modell hat, werden auf der resultierenden Seite die aktivierten Kontrollkästchen nicht angezeigt, obwohl das Modell die Werte als wahr hat. Ich bin mir nicht sicher, was Sie mit "GET Action" meinen, außer vielleicht, um es in meinem Controller auf true zu setzen, aber ich habe es dort bereits auf true gesetzt. Irgendeine Idee, was mir fehlt?
Kirk Liemohn
Ich habe eine Antwort gepostet, die für mich funktioniert hat. Nicht ideal, aber ich habe es zum Laufen gebracht.
Kirk Liemohn
8

Ich hatte ein Problem mit ASP.NET MVC 5, bei dem CheckBoxFor meine Kontrollkästchen bei einem serverseitigen Validierungsfehler nicht aktivierte, obwohl für mein Modell eindeutig der Wert true festgelegt war. Mein Razor Markup / Code sah aus wie:

@Html.CheckBoxFor(model => model.MyBoolValue, new { @class = "mySpecialClass" } )

Damit dies funktioniert, musste ich Folgendes ändern:

@{
    var checkboxAttributes = Model.MyBoolValue ?
        (object) new { @class = "mySpecialClass", @checked = "checked" } :
        (object) new { @class = "mySpecialClass" };
}
@Html.CheckBox("MyBoolValue", checkboxAttributes)
Kirk Liemohn
quelle
1
Ich hatte das gleiche Problem, in meinem Fall kann ich ModelState.Clear verwenden. Liegt das daran, dass Ihr Postback-Wert verwendet wird und nicht das, was Sie im Controller eingestellt haben? weblog.west-wind.com/posts/2012/Apr/20/…
Tony
7

Platzieren Sie dies auf Ihrem Modell:

[DisplayName("Electric Fan")]
public bool ElectricFan { get; set; }

private string electricFanRate;

public string ElectricFanRate
{
    get { return electricFanRate ?? (electricFanRate = "$15/month"); }
    set { electricFanRate = value; }
}

Und das in Ihrem cshtml:

<div class="row">
    @Html.CheckBoxFor(m => m.ElectricFan, new { @class = "" })
    @Html.LabelFor(m => m.ElectricFan, new { @class = "" })
    @Html.DisplayTextFor(m => m.ElectricFanRate)
</div>

Welches wird dies ausgeben:

MVC-Ausgabe Wenn Sie auf das Kontrollkästchen oder die fett gedruckte Bezeichnung klicken, wird das Kontrollkästchen aktiviert / deaktiviert

James Gray
quelle
4

Keine der oben genannten Antworten hat bei der Bindung an POST für mich funktioniert, bis ich in CSHTML Folgendes hinzugefügt habe

<div class="checkbox c-checkbox">
    <label>
        <input type="checkbox" id="xPrinting" name="xPrinting" value="true"  @Html.Raw( Model.xPrinting ? "checked" : "")>
        <span class=""></span>Printing
    </label>
</div>


// POST: Index

[HttpPost]
public ActionResult Index([Bind(Include = "dateInHands,dateFrom,dateTo,pgStatus,gpStatus,vwStatus,freeSearch,xPrinting,xEmbroidery,xPersonalization,sortOrder,radioOperator")] ProductionDashboardViewModel model)
Craig Trombly
quelle
1

Ich suchte nach einer Lösung, um das Etikett dynamisch aus einer Datenbank wie folgt anzuzeigen:

checkbox1 : Option 1 text from database
checkbox2 : Option 2 text from database
checkbox3 : Option 3 text from database
checkbox4 : Option 4 text from database

Da keine der oben genannten Lösungen für mich funktioniert hat, habe ich Folgendes verwendet:

 @Html.CheckBoxFor(m => m.Option1, new { @class = "options" }) 
 <label for="Option1">@Model.Option1Text</label>

 @Html.CheckBoxFor(m => m.Option2, new { @class = "options" }) 
 <label for="Option2">@Mode2.Option1Text</label>

Auf diese Weise wird das Kontrollkästchen aktiviert, wenn der Benutzer auf die Beschriftung klickt.

Könnte es sein, dass es jemandem helfen kann.

Ali Adravi
quelle
1

Ich hatte Probleme, dies zum Laufen zu bringen, und fügte eine weitere Lösung für alle hinzu, die FromCollection verwenden möchten / müssen.

Anstatt von:

@Html.CheckBoxFor(model => true, item.TemplateId) 

Formatieren Sie den HTML-Helfer wie folgt:

@Html.CheckBoxFor(model => model.SomeProperty, new { @class = "form-control", Name = "SomeProperty"})

Dann im Ansichtsmodell / Modell, wo immer Ihre Logik ist:

public void Save(FormCollection frm)
{   
    // to do instantiate object.

    instantiatedItem.SomeProperty = (frm["SomeProperty"] ?? "").Equals("true", StringComparison.CurrentCultureIgnoreCase);

    // to do and save changes in database.
}

quelle