Comment puis-je ajouter un élément à une SelectList dans ASP.net MVC

112

Fondamentalement, je cherche à insérer un élément au début d'une SelectList avec la valeur par défaut de 0 et la valeur de texte de "- Sélectionnez un -"

Quelque chose comme

SelectList list = new SelectList(repository.func.ToList());
ListItem li = new ListItem(value, value);
list.items.add(li);

Cela peut-il être fait?

GEOCHET
la source
2
SelectListsemble vraiment être juste une aide pour lier les données directement aux éléments. Si vous ajoutez des éléments manuellement, utilisez à la List<SelectListItem>place.
Kai Hartmann
Compte tenu de la réponse acceptée et du nombre de votes, puis-je vous suggérer de modifier légèrement la question pour refléter cette réponse i, e, "Comment puis-je ajouter un élément de valeur vide à une SelectList dans ASP.net MVC"? Mais merci et merci à @ h-dog d'avoir répondu à la question originale "Comment puis-je ajouter un élément" en soi
AndrewD

Réponses:

150

Il n'est vraiment pas nécessaire de le faire à moins que vous n'insistiez sur la valeur 0. L'extension HtmlHelper DropDownList vous permet de définir une étiquette d'option qui apparaît comme la valeur initiale dans la sélection avec une valeur nulle. Utilisez simplement l'une des signatures DropDownList qui a l'étiquette d'option.

<%= Html.DropDownList( "DropDownValue",
                       (IEnumerable<SelectListItem>)ViewData["Menu"],
                        "-- Select One --" ) %>
Tvanfosson
la source
1
Et si vous insistiez réellement sur la valeur de 0? Si la valeur est null / une chaîne vide, cela peut entraîner des problèmes de liaison de modèle.
Kjensen
2
Si vous l'attendez comme un int, alors j'utiliserais int? et laissez-le toujours nul si aucune sélection n'a été effectuée.
tvanfosson
13
Le problème avec cette solution est que vous perdez l'élément sélectionné.
37Stars
1
@JesseWebb Je suppose que vous avez juste besoin de vous assurer que vous utilisez une signature qui inclut l'étiquette d'option, msdn.microsoft.com/en-us/library/ee703567.aspx , @Html.DropDownListFor( m => m.MenuSelection, (IEnumerable<SelectListItem>)ViewBag.Menu, "Select One", null )par exemple, y compris la valeur null htmlAttributespour éviter toute confusion avec la signature qui prend une expression, l'énumération de menu et un objet (htmlAttributes).
tvanfosson
1
@tvanfosson - Merci pour cette clarification. J'ai essayé de l'utiliser avec un type Complex comme type de IEnumerable dans la SelectList. J'ai dû spécifier le dataValueFieldet le dataTestFieldqui faisait que cela ne fonctionnait pas lors de l'ajout d'une valeur optionLabel. Cela aurait probablement pu fonctionner avec un peu plus d'efforts, mais je viens d'utiliser l'une des solutions alternatives. Merci quand même!
Jesse Webb
82

J'ai fait fonctionner cela en remplissant un SelectListItem, en le convertissant en liste et en ajoutant une valeur à l'index 0.

List<SelectListItem> items = new SelectList(CurrentViewSetups, "SetupId", "SetupName", setupid).ToList(); 
items.Insert(0, (new SelectListItem { Text = "[None]", Value = "0" }));
ViewData["SetupsSelectList"] = items;
davewilliams459
la source
Je recommande d'utiliser la surcharge optionLabel dans HtmlHelper -> @ Html.DropDownListFor
2b77bee6-5445-4c77-b1eb-4df3e5
17

C'est possible.

//Create the select list item you want to add
SelectListItem selListItem = new SelectListItem() { Value = "null", Text = "Select One" };

//Create a list of select list items - this will be returned as your select list
List<SelectListItem> newList = new List<SelectListItem>();

//Add select list item to list of selectlistitems
newList.Add(selListItem);

//Return the list of selectlistitems as a selectlist
return new SelectList(newList, "Value", "Text", null);
eaf
la source
Je recommande d'utiliser la surcharge optionLabel dans HtmlHelper -> @ Html.DropDownListFor
2b77bee6-5445-4c77-b1eb-4df3e5
13

J'ai aimé la réponse de @ AshOoO mais comme @Rajan Rawal, j'avais besoin de conserver l'état de l'élément sélectionné, le cas échéant. J'ai donc ajouté ma personnalisation à sa méthodeAddFirstItem()

public static SelectList AddFirstItem(SelectList origList, SelectListItem firstItem)
{
    List<SelectListItem> newList = origList.ToList();
    newList.Insert(0, firstItem);

    var selectedItem = newList.FirstOrDefault(item => item.Selected);
    var selectedItemValue = String.Empty;
    if (selectedItem != null)
    {
        selectedItemValue = selectedItem.Value;
    }

    return new SelectList(newList, "Value", "Text", selectedItemValue);
}
Chien H
la source
Je recommande d'utiliser la surcharge optionLabel dans HtmlHelper -> @ Html.DropDownListFor
2b77bee6-5445-4c77-b1eb-4df3e5
5
private SelectList AddFirstItem(SelectList list)
        {
            List<SelectListItem> _list = list.ToList();
            _list.Insert(0, new SelectListItem() { Value = "-1", Text = "This Is First Item" });
            return new SelectList((IEnumerable<SelectListItem>)_list, "Value", "Text");
        }

Cela devrait faire ce dont vous avez besoin, envoyez simplement votre liste de sélection et elle renverra une liste de sélection avec un élément dans l'index 0

Vous pouvez personnaliser le texte, la valeur ou même l'index de l'élément que vous devez insérer

AshOoO
la source
et si j'ai des valeurs sélectionnées et que je souhaite les préserver?
Rajan Rawal
Je recommande d'utiliser la surcharge optionLabel dans HtmlHelper -> @ Html.DropDownListFor
2b77bee6-5445-4c77-b1eb-4df3e5
5

Voici une aide html pour vous

public static SelectList IndividualNamesOrAll(this SelectList Object)
{
    MedicalVarianceViewsDataContext LinqCtx = new MedicalVarianceViewsDataContext();

    //not correct need individual view!
    var IndividualsListBoxRaw =  ( from x in LinqCtx.ViewIndividualsNames 
                                 orderby x.FullName
                                 select x);

    List<SelectListItem> items = new SelectList (
                               IndividualsListBoxRaw, 
                              "First_Hospital_Case_Nbr", 
                              "FullName"
                               ).ToList();

    items.Insert(0, (new SelectListItem { Text = "All Individuals", 
                                        Value = "0.0", 
                                        Selected = true }));

    Object = new SelectList (items,"Value","Text");

    return Object;
}
caché
la source
3

La méthode .ToList (). Insert (..) place un élément dans votre liste. N'importe quelle position peut être spécifiée. Après ToList, ajoutez simplement .Insert (0, "- - Premier élément - -")

Votre code

SelectList list = new SelectList(repository.func.ToList());
ListItem li = new ListItem(value, value);
list.items.add(li);

Nouveau code

SelectList list = new SelectList(repository.func.ToList().Insert(0, "- - First Item - -"));
ListItem li = new ListItem(value, value);
list.items.add(li);
Moji
la source
2

Cela peut ne pas sembler très élégant, mais je fais généralement quelque chose comme ceci:

    var items = repository.func.ToList();
    items.Insert(0, new funcItem { ID = 0, TextValue = "[None]" });
    ViewBag.MyData = new SelectList(items);
Androiderson
la source
1

D'accord, j'aime le code propre, alors j'ai fait de cette méthode d'extension

static public class SelectListHelper
{
    static public SelectList Add(this SelectList list, string text, string value = "", ListPosition listPosition = ListPosition.First)
    {
        if (string.IsNullOrEmpty(value))
        {
            value = text;
        }
        var listItems = list.ToList();
        var lp = (int)listPosition;
        switch (lp)
        {
            case -1:
                lp = list.Count();
                break;
            case -2:
                lp = list.Count() / 2;
                break;
            case -3:
                var random = new Random();
                lp = random.Next(0, list.Count());
                break;
        }
        listItems.Insert(lp, new SelectListItem { Value = value, Text = text });
        list = new SelectList(listItems, "Value", "Text");
        return list;
    }

    public enum ListPosition
    {
        First = 0,
        Last = -1,
        Middle = -2,
        Random = -3
    }
}

Utilisation (par exemple):

var model = new VmRoutePicker
    {
     Routes =
     new SelectList(_dataSource.Routes.Select(r => r.RouteID).Distinct())
     };                                     
  model.Routes = model.Routes.Add("All", "All", SelectListHelper.ListPosition.Random);
//or
  model.Routes = model.Routes.Add("All");
Jeff
la source
1

Comme cette option peut nécessiter de nombreuses manières différentes, je suis parvenu à la conclusion de développer un objet afin qu'il puisse être utilisé dans différents scénarios et dans de futurs projets

ajoutez d'abord cette classe à votre projet

public class SelectListDefaults
{
    private IList<SelectListItem> getDefaultItems = new List<SelectListItem>();

    public SelectListDefaults()
    {
        this.AddDefaultItem("(All)", "-1");
    }
    public SelectListDefaults(string text, string value)
    {
        this.AddDefaultItem(text, value);
    }
    public IList<SelectListItem> GetDefaultItems
    {
        get
        {                
            return getDefaultItems;
        }

    }
    public void AddDefaultItem(string text, string value)
    {        
        getDefaultItems.Add(new SelectListItem() { Text = text, Value = value });                    
    }
}

Maintenant, dans Controller Action, vous pouvez faire comme ça

    // Now you can do like this
    ViewBag.MainCategories = new SelectListDefaults().GetDefaultItems.Concat(new SelectList(db.MainCategories, "MainCategoryID", "Name", Request["DropDownListMainCategory"] ?? "-1"));
    // Or can change it by such a simple way
    ViewBag.MainCategories = new SelectListDefaults("Any","0").GetDefaultItems.Concat(new SelectList(db.MainCategories, "MainCategoryID", "Name", Request["DropDownListMainCategory"] ?? "0"));
    // And even can add more options
    SelectListDefaults listDefaults = new SelectListDefaults();
    listDefaults.AddDefaultItme("(Top 5)", "-5");
    // If Top 5 selected by user, you may need to do something here with db.MainCategories, or pass in parameter to method 
    ViewBag.MainCategories = listDefaults.GetDefaultItems.Concat(new SelectList(db.MainCategories, "MainCategoryID", "Name", Request["DropDownListMainCategory"] ?? "-1"));

Et enfin dans View, vous coderez comme ça.

@Html.DropDownList("DropDownListMainCategory", (IEnumerable<SelectListItem>)ViewBag.MainCategories, new { @class = "form-control", onchange = "this.form.submit();" })
sairfan
la source
0

Une solution consiste à utiliser la réponse de @ tvanfosson (la réponse sélectionnée) et à utiliser JQuery (ou Javascript) pour définir la valeur de l'option sur 0:

$(document).ready(function () {
        $('#DropDownListId option:first').val('0');
    });

J'espère que cela t'aides.

logique
la source
0

Essayez quelque chose comme le code suivant:

MyDAO MyDAO = new MyDAO();    
List<MyViewModel> _MyDefault = new List<MyViewModel>() {
                new MyViewModel{
                    Prop1= "All",
                    Prop2 = "Select all"
                }
            };
            ViewBag.MyViewBag= 
                new SelectList(MyDAO
                .MyList().Union(
                    _MyDefault
                    ), "Prop1", "Prop2");
Enrique Mingyar Torrez Hinojos
la source
-5

Je ne sais pas si quelqu'un d'autre a une meilleure option ...

<% if (Model.VariableName == "" || Model.VariableName== null) { %>
   <%= html.DropDpwnList("ListName", ((SelectList) ViewData["viewName"], "", 
        new{stlye=" "})%>
<% } else{ %>
<%= html.DropDpwnList("ListName", ((SelectList) ViewData["viewName"], 
        Model.VariableName, new{stlye=" "})%>
<% }>
Nouveau2 ceci
la source