2010-06-14 3 views
11

Avec un modèle de vue contenant le champ:carte MVC à annulable bool dans le modèle

public bool? IsDefault { get; set; } 

je reçois une erreur en essayant de la carte dans la vue:

<%= Html.CheckBoxFor(model => model.IsDefault) %> 

Impossible de convertir implicitement le type ' bool? à 'bool'. Une conversion explicite existe (est-ce qu'il vous manque un casting?)

J'ai essayé de lancer, et en utilisant .Value et ni travaillé.

Notez le comportement que je souhaite est que la soumission du formulaire doit définir IsDefault dans le modèle à true ou false. Une valeur de null signifie simplement que le modèle n'a pas été rempli.

+0

Pourquoi devriez-vous vérifier si le modèle a été rempli? Peut-être qu'il y a une autre façon, une bonne façon de faire ce que vous devez faire? – AlexanderMP

+0

duplication possible de [Pourquoi CheckBoxFor génère-t-elle une erreur d'exécution] (http://stackoverflow.com/questions/2490790/why-is-checkboxfor-producing-runtime-error) –

Répondre

13

Le problème est que vous avez vraiment trois valeurs possibles; true, false et null, donc le CheckBoxFor ne peut pas gérer les trois états (seulement deux états). Brad Wilson discute sur son blog here

Il utilise un DropDownList pour les booléens Nullable.

Ce StackOverflow question décrit mieux la situation que je ne l'ai fait ci-dessus. L'inconvénient de la solution est parfois nullable n'implique pas faux, il devrait être nul. Un exemple de ceci serait des critères de filtre où vous ne voulez pas que vrai ou faux soit appliqué.

7

Si vous ne se soucient pas de la valeur nulle, et que vous voulez juste la case soit cochée lorsque son null, vous pouvez effectuer les opérations suivantes:

Créer une autre propriété de type bool dans votre modèle comme celui-ci:

public bool NotNullableBool 
{ 
    get 
    { 
     return NullableBool == true; 
    } 
    set 
    { 
     NullableBool = value; 
    } 
} 

Ensuite, il suffit d'utiliser que pour la liaison ...

+1

get {_return_ NullableBool == true; } * FIFY – vbullinger

+1

Cela a fonctionné un régal pour moi, puis lier mon CheckboxFor à mon NotNullableBool – Alicia

2

pour moi, cela est beaucoup mieux:

<%= Html.CheckBox("IsDefault", Model.IsDefault.HasValue? Model.IsDefault : false) %> 
+1

C'est bien pour True/False, mais si vous voulez gérer un vrai bool ?, vous devez également gérer Null (Pensez à cela Oui, Non et Inconnu.) – Greg

+0

Il gère null car 'Model.IsDefault.HasValue' sera vérifié, trouvé comme nul, et donnera' false' comme résultat. En général, nous ne nous soucions pas si quelque chose est 'nul' dans nos variables 'vrai/faux' --- nous voulons juste savoir quand quelque chose est vrai/rencontré. – vapcguy

+2

Souvent c'est vrai. Mais parfois, les gens veulent savoir le différent entre vrai connu, connu faux, et juste non fourni/inconnu. Nous avons des champs comme mariés. Mais nous voulons savoir qu'ils sont effectivement mariés, ou choisis comme non mariés, ou si les données n'ont pas été saisies. Si plusieurs personnes gèrent l'enregistrement, le suivant peut poser la question si elle n'a jamais été demandée. Mais si vous le montrez simplement comme faux, les gens supposeraient qu'il a été demandé et retourné comme faux. – Greg

0

Pour ajouter à vapcguy réponse, une autre plus « propre » façon de le faire est comme suit

@Html.CheckBox("IsDefault", Model?.IsDefault) 

Ou

<%= Html.CheckBox("IsDefault", Model?.IsDefault) %> 
0

Vous pouvez créer un modèle d'éditeur pour rendre une case à cocher pour nullables booléens. Nommez le modèle Boolean.cshtml pour l'utiliser par défaut pour toutes les propriétés booléennes du site.Assurez-vous que le fichier est dans le dossier ~/Vues/shared/EditorTemplates

@model bool? 
@Html.CheckBox(String.Empty, Model??false) 
1

Voici comment mapper un bullable booléen bool? propriété dans un DropDownListFor:

@model SomeModel 

<!-- ...some HTML... --> 

@Html.DropDownListFor(m => m.NullableBooleanProperty, new SelectList(
     new[] { 
      new { Value = "", Text = "-- Choose YES or NO --" }, 
      new { Value = "true", Text = "YES" }, 
      new { Value = "false", Text = "NO" }, 
     }, 
     "Value", 
     "Text" 
    )) 

Et voici comment la carte à un CheckBoxFor en utilisant un propriété non annulable proxy comme solution de contournement:

Dans le ViewModel:

public bool NullableBooleanPropertyProxy 
{ 
    get 
    { 
     return NullableBooleanProperty == true; 
    } 
    set 
    { 
     NullableBooleanProperty = value; 
    } 
} 

Dans la vue:

@model SomeModel 

<!-- ...some HTML... --> 

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

Le seul inconvénient de cette solution est que la valeur null sera traitée comme false: si vous ne pouvez pas accepter cela, il est préférable d'utiliser un contrôle qui peut prendre en charge trois états, tels que le DropDownListFor susmentionné.

Pour plus d'informations, read here.

+0

Merci cela a fonctionné un régal pour l'exemple de case à cocher – Alicia