web-dev-qa-db-fra.com

ASP.NET MVC DropDownListFor avec un modèle de type List <string>

J'ai une vue avec un modèle de type List<string> et je veux placer sur la page une liste déroulante contenant toutes les chaînes de la liste en tant qu'éléments du menu déroulant. Je suis nouveau chez MVC, comment pourrais-je accomplir cela?

J'ai essayé ceci:

@model List<string>
@Html.DropDownListFor(x => x)

mais cela a jeté une erreur.

46
Chev

Pour créer une liste déroulante, vous avez besoin de deux propriétés:

  1. une propriété à laquelle vous lierez (généralement une propriété scalaire de type entier ou chaîne)
  2. une liste d'éléments contenant deux propriétés (une pour les valeurs et une pour le texte)

Dans votre cas, vous n'avez qu'une liste de chaînes qui ne peut pas être exploitée pour créer une liste déroulante utilisable.

Tandis que pour le numéro 2, vous pourriez avoir la valeur et le texte identiques, vous avez besoin d’une propriété à associer. Vous pouvez utiliser une version faiblement typée de l’aide:

@model List<string>
@Html.DropDownList(
    "Foo", 
    new SelectList(
        Model.Select(x => new { Value = x, Text = x }),
        "Value",
        "Text"
    )
)

Foo sera le nom du fichier ddl utilisé par le classeur de modèle par défaut. Ainsi, le balisage généré pourrait ressembler à ceci:

<select name="Foo" id="Foo">
    <option value="item 1">item 1</option>
    <option value="item 2">item 2</option>
    <option value="item 3">item 3</option>
    ...
</select>

Ceci étant dit, un modèle de visualisation bien meilleur pour une liste déroulante est le suivant:

public class MyListModel
{
    public string SelectedItemId { get; set; }
    public IEnumerable<SelectListItem> Items { get; set; }
}

et alors:

@model MyListModel
@Html.DropDownListFor(
    x => x.SelectedItemId,
    new SelectList(Model.Items, "Value", "Text")
)

et si vous voulez présélectionner une option dans cette liste, il vous suffit de définir la propriété SelectedItemId de ce modèle de vue sur le Value correspondant à un élément du Items collection.

120
Darin Dimitrov

Si vous avez une liste de type chaîne que vous souhaitez dans une liste déroulante, procédez comme suit:

EDIT: Clarifié, ce qui en fait un exemple plus complet.

public class ShipDirectory
{
    public string ShipDirectoryName { get; set; }
    public List<string> ShipNames { get; set; }
}

ShipDirectory myShipDirectory = new ShipDirectory()
{
    ShipDirectoryName = "Incomming Vessels",
    ShipNames = new List<string>(){"A", "A B", "A B C"},
}

myShipDirectory.ShipNames.Add("Aunt Bessy");

@Html.DropDownListFor(x => x.ShipNames, new SelectList(Model.ShipNames), "Select a Ship...", new { @style = "width:500px" })

Ce qui donne une liste déroulante comme ceci:

<select id="ShipNames" name="ShipNames" style="width:500px">
    <option value="">Select a Ship...</option>
    <option>A</option>
    <option>A B</option>
    <option>A B C</option>
</select>

Pour obtenir la valeur sur un post de contrôleurs; Si vous utilisez un modèle (par exemple, MyViewModel) qui a la propriété Liste de chaînes, car vous avez spécifié x => x.ShipNames, vous avez simplement la signature de la méthode (car elle sera sérialisée/désérialisée dans le modèle):

public ActionResult MyActionName (modèle MyViewModel)

Si vous souhaitez simplement accéder à la liste déroulante après la publication, la signature devient:

public ActionResult MyActionName (string ShipNames)

4
Paul Zahra

Je me rends compte que cette question a été posée il y a longtemps, mais je suis venu ici pour chercher des réponses et je n'étais pas satisfait de tout ce que je pouvais trouver. J'ai finalement trouvé la réponse ici:

https://www.tutorialsteacher.com/mvc/htmlhelper-dropdownlist-dropdownlistfor

Pour obtenir les résultats du formulaire, utilisez FormCollection, puis extrayez chaque valeur individuelle par son nom de modèle, comme suit:

yourRecord.FieldName = Request.Form["FieldNameInModel"];

Autant que je sache, le nom de l'argument que vous donnez à FormCollection ne fait aucune différence. Utilisez Request.Form ["NameFromModel"] pour le récupérer.

Non, je n'ai pas creusé pour voir comment cette magie opère sous les couvertures. Je sais juste que ça marche ...

J'espère que cela aidera quelqu'un à éviter les heures que j'ai passées à essayer différentes approches avant de le faire fonctionner.

0
DaveN59