107 votes

MVC3 : Création de case à cocher pour boolean nullable

Mon modèle a un booléen qui doit être nullable

 public bool? Foo
{
   get;
   set;
}
 

donc dans mon rasoir cshtml j'ai

 @Html.CheckBoxFor(m => m.Foo)
 

sauf que ça ne marche pas. Pas plus que de le lancer avec (bool). Si je fais

 @Html.CheckBoxFor(m => m.Foo.Value)
 

cela ne crée pas d'erreur, mais ne lie pas mon modèle une fois publié et foo est défini sur null. Quel est le meilleur moyen d'afficher Foo sur la page et de le lier à mon modèle sur un article?

118voto

AFinkelstein Points 3291

Je l'ai avec pour travailler

 @Html.EditorFor(Model.Foo)
 

puis faire un Boolean.cshtml dans mon dossier EditorTemplates et coller

 @model bool?

@Html.CheckBox("", Model.GetValueOrDefault())
 

à l'intérieur.

25voto

VitalyB Points 91

J'ai bool? IsDisabled {get; ensemble; } dans Modèle. Inséré si dans la vue.

   <div class="inputClass" id="disabled">
    <div>
     @if(Model.IsDisabled==null)
    {
        Model.IsDisabled = false;
    }           
        @Html.CheckBoxFor(model => model.IsDisabled.Value)         
    </div>
</div> 
 

16voto

Darin Dimitrov Points 528142

Mon modèle est une valeur booléenne qui doit être nullable

Pourquoi? Ce n'est pas logique. Une case à cocher a deux états: cochée/décochée, ou Vrai/Faux, si vous voulez. Il n'y a aucun état tiers.

Ou attendez vous à l'aide de votre domaine de modèles à votre point de vue au lieu d'afficher des modèles? C'est votre problème. Donc la solution pour moi est d'utiliser un modèle d'affichage dans lequel vous allez définir une simple propriété booléenne:

public class MyViewModel
{
    public bool Foo { get; set; }
}

et maintenant, vous aurez votre action de contrôleur passer ce modèle d'affichage de la vue et de générer de la case appropriée.

8voto

Jules Bartow Points 419

Compliquant une primitive avec des champs cachés de préciser si False ou Null n'est pas recommandé.

Case à cocher n'est pas ce que vous devriez être en utilisant -- il n'a en fait qu'un état: Vérifié. Sinon, il pourrait être n'importe quoi.

Lorsque votre champ de base de données est un boolean nullable (bool?), le UX devez utiliser de 3 Boutons Radio, où le premier bouton représente votre "Checked", le deuxième bouton représente "Non Vérifié" et le troisième bouton représente votre null, quelle que soit la sémantique de null. Vous pouvez utiliser un <select><option> la liste déroulante enregistrer l'immobilier, mais l'utilisateur doit cliquer deux fois et les choix ne sont pas presque aussi instantanément clair.

  1     0      null 
True  False  Not Set
Yes   No     Undecided
Male  Female Unknown
On    Off    Not Detected

Le RadioButtonList, défini comme une extension nommée RadioButtonForSelectList, s'appuie sur les boutons pour vous, y compris la sélection, la valeur, et définit l' <div class="RBxxxx"> de sorte que vous pouvez utiliser css pour faire de votre radio boutons aller à l'horizontale (display: inline-block), à la verticale, ou dans une table de la mode (display: inline-block; width:100px;)

Dans le modèle (je suis l'aide de la chaîne, chaîne pour la définition du dictionnaire comme un exemple pédagogique. Vous pouvez utiliser bool?, chaîne de caractères)

public IEnumerable<SelectListItem> Sexsli { get; set; }
       SexDict = new Dictionary<string, string>()
        {
                { "M", "Male"},
                { "F", "Female" },
                { "U", "Undecided" },

        };

        //Convert the Dictionary Type into a SelectListItem Type
        Sexsli = SexDict.Select(k =>
              new SelectListItem
              {
                  Selected = (k.Key == "U"),
                  Text = k.Value,
                  Value = k.Key.ToString()
              });

<fieldset id="Gender">
<legend id="GenderLegend" title="Gender - Sex">I am a</legend>
    @Html.RadioButtonForSelectList(m => m.Sexsli, Model.Sexsli, "Sex") 
        @Html.ValidationMessageFor(m => m.Sexsli)
</fieldset>

public static class HtmlExtensions
{
public static MvcHtmlString RadioButtonForSelectList<TModel, TProperty>(
    this HtmlHelper<TModel> htmlHelper,
    Expression<Func<TModel, TProperty>> expression,
    IEnumerable<SelectListItem> listOfValues,
    String rbClassName = "Horizontal")
{
var metaData = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
var sb = new StringBuilder();

if (listOfValues != null)
{
    // Create a radio button for each item in the list 
    foreach (SelectListItem item in listOfValues)
    {
        // Generate an id to be given to the radio button field 
        var id = string.Format("{0}_{1}", metaData.PropertyName, item.Value);

        // Create and populate a radio button using the existing html helpers 
        var label = htmlHelper.Label(id, HttpUtility.HtmlEncode(item.Text));

        var radio = String.Empty;

        if (item.Selected == true)
        {
            radio = htmlHelper.RadioButtonFor(expression, item.Value, new { id = id, @checked = "checked" }).ToHtmlString();
        }
        else
        {
            radio = htmlHelper.RadioButtonFor(expression, item.Value, new { id = id }).ToHtmlString();

        }// Create the html string to return to client browser
        // e.g. <input data-val="true" data-val-required="You must select an option" id="RB_1" name="RB" type="radio" value="1" /><label for="RB_1">Choice 1</label> 

        sb.AppendFormat("<div class=\"RB{2}\">{0}{1}</div>", radio, label, rbClassName);
    }
}

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

4voto

Paul Points 1425

Pour moi la solution a été de changer le modèle de vue. Considérez que vous êtes à la recherche pour les factures. Ces factures peuvent être payées ou non. Si votre recherche comporte trois options: Rémunéré, non rémunéré, ou "I don't Care".

J'ai eu ce défini à l'origine comme un booléen? champ:

public bool? PaidInvoices { get; set; }

Cela m'a fait tomber sur cette question. J'ai créé un type Enum et je traitées comme suit:

@Html.RadioButtonFor(m => m.PaidInvoices, PaidStatus.NotSpecified, new { @checked = true })
@Html.RadioButtonFor(m => m.PaidInvoices, PaidStatus.Yes) 
@Html.RadioButtonFor(m => m.PaidInvoices, PaidStatus.No)

Bien sûr, je les avait enveloppés dans des étiquettes et avait de texte spécifié, je veux seulement dire ici est une autre option à envisager.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X