J'ai la méthode Action suivante, qui ont un viewBag avec une liste de chaînes: -
public ActionResult Login(string returnUrl)
{
List<string> domains = new List<string>();
domains.Add("DomainA");
ViewBag.ReturnUrl = returnUrl;
ViewBag.Domains = domains;
return View();
}
et sur la vue, j'essaie de construire une liste déroulante qui montre les chaînes de viewBag comme suit: -
@Html.DropDownList("domains",(SelectList)ViewBag.domains )
Mais j'ai eu l'erreur suivante: -
Impossible de convertir le type 'System.Collections.Generic.List' en 'System.Web.Mvc.SelectList'
Alors quelqu'un peut-il dire pourquoi je ne peux pas remplir ma liste déroulante d'une liste de piqûres?
Parce que DropDownList
ne accepte pas une liste de chaînes. Il accepte IEnumerable<SelectListItem>
. C'est votre responsabilité de convertir votre liste de chaînes en cela. C'est assez facile cependant:
domains.Select(m => new SelectListItem { Text = m, Value = m })
Ensuite, vous pouvez nourrir cela à DropDownList
:
@Html.DropDownList("domains", ((List<string>)ViewBag.domains).Select(m => new SelectListItem { Text = m, Value = m }))
ViewBag n'est pas fortement typé. Vous pouvez utiliser les classes ViewModel pour transmettre des instances à une vue afin que cette vue puisse utiliser plusieurs sources de données.
public ActionResult Login(string returnUrl)
{
List<string> domains = new List<string>();
domains.Add("DomainA");
ViewModel model=new ViewModel();
model.ReturnUrl = returnUrl;
model.Domains =new SelectList(domains);
return View(model);
}
Public Class ViewModel()
{
property Url ReturnUrl{get;set;}
property SelectList Domains{get;set;}
}
Pour compléter la réponse de Chris Pratt, voici un exemple de code permettant de créer la liste déroulante:
@Html.DropDownList("domains", new SelectList(((List<string>)ViewBag.domains).Select(d => new SelectListItem { Text = d, Value = d }), "Value", "Text"))
Ce qui produira le balisage suivant:
<select id="domains" name="domains">
<option value="item 1">item 1</option>
<option value="item 2">item 2</option>
<option value="item 3">item 3</option>
</select>
@Html.DropDownListFor(
m => m.Country,
new SelectList(_CountryList, "CountryID", "Title"),
new { @class = "form-control" }
)
Vous devez vraiment avoir une "clé", ou un index, pour chaque valeur, car vous devez convertir chaque nom en un IEnumerable<SelectListItem>
, ce qui nécessite une valeur d'ID et une chaîne de texte à afficher. Vous pouvez le faire de deux manières:
Utilise un dictionnaire
Faire un Dictionary<int, string>
:
Dictionary<int, string> domainDict = new Dictionary<int, string>();
et chaque fois que vous ajoutez un domaine, vous ajoutez un numéro:
domainDict.Add(1, "DomainA");
Si vous avez une liste source pour cette information avec plusieurs domaines, vous pouvez créer une variable foreach
sur cette liste et utiliser une variable d'indexeur similaire à celle que je présente, ci-dessous, au lieu d'ajouter manuellement les éléments.
Vous aurez besoin d'un modèle. Créez une classe appelée DomainViewModel.cs
et ajoutez ceci à l'intérieur:
public class DomainViewModel()
{
public int Id { get; set; }
public string Name { get; set; }
}
Ensuite, parcourez votre dictionnaire pour ajouter les éléments à une DomainViewModel
, puis ajoutez chacun de ces éléments à un List<DomainViewModel>
, similaire à ce que j'ai ci-dessous dans la section suivante, sauf que cela ressemblerait à ceci:
List<DomainViewModel> lstDomainModel = new List<DomainViewModel>();
foreach(KeyValuePair<int, string> kvp in domainDict)
{
DomainViewModel d = new DomainViewModel();
d.Id = kvp.Key; // number
d.Name = kvp.Value; // domain name
lstDomainModel.Add(d);
}
(Passer à Finition , ci-dessous)
Liste des itérations avec indexeur de boucle
Si vous ne souhaitez pas utiliser un Dictionary<>
, vous pouvez simplement ajouter l'index à la volée en itérant le List<string>
et en le mettant directement dans un List<DomainViewModel>
. Voici comment vous feriez cela:
1) Assurez-vous d'avoir créé la classe DomainViewModel.cs
ci-dessus.
2) Modifiez votre fonction de contrôleur pour créer votre List<string>
, puis parcourez-la pour l'ajouter par fragments de DomainViewModel
à un nouveau List<DomainViewModel>
à l'aide d'une variable d'indexation (idx
):
List<string> domains = new List<string>();
domains.Add("DomainA"); // etc.
List<DomainViewModel> lstDomainModel = new List<lstDomainModel>();
int idx = 0;
// Add your List<string> to your List<DomainViewModel>
foreach (string s in domainList)
{
DomainViewModel domainModel = new DomainViewModel();
domainModel.Id = idx;
domainModel.Name = s;
lstDomainModel.Add(domainModel);
idx++;
}
Finir
En utilisant l'une ou l'autre méthode, une fois que vous l'avez dans un List<DomainViewModel>
, vous pouvez faire:
IEnumerable<SimpleListItem> domainList =
lstDomainModel.Select(d => new SelectListItem {
Text = d.Name,
Value = d.Id.ToString()
}
);
ViewBag.Domains = domainList;
Et montrez-le dans votre vue comme ceci:
@Html.DropDownList("Domains", (IEnumerable<SelectListItem>)ViewBag.Domains)