¿Cómo puedo agregar un elemento a una SelectList en ASP.net MVC?

112

Básicamente, estoy buscando insertar un elemento al comienzo de una lista de selección con el valor predeterminado de 0 y el valor de texto de "- Seleccionar uno -"

Algo como

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

Se puede hacer esto?

GEOCHET
fuente
2
SelectListrealmente parece ser solo una ayuda para vincular datos directamente a los elementos. Si agrega elementos manualmente, utilice List<SelectListItem>en su lugar.
Kai Hartmann
Dada la respuesta aceptada y el número de votos, ¿podría sugerirle que cambie ligeramente la pregunta para reflejar esa respuesta i, e, "¿Cómo puedo agregar un elemento de valor en blanco a una SelectList en ASP.net MVC"? Pero crédito y agradecimiento a @ h-dog por responder a la pregunta original "¿Cómo puedo agregar un artículo?"
AndrewD

Respuestas:

150

Realmente no es necesario hacer esto a menos que insista en el valor de 0. La extensión HtmlHelper DropDownList le permite establecer una etiqueta de opción que aparece como el valor inicial en la selección con un valor nulo. Simplemente use una de las firmas DropDownList que tiene la etiqueta de opción.

<%= Html.DropDownList( "DropDownValue",
                       (IEnumerable<SelectListItem>)ViewData["Menu"],
                        "-- Select One --" ) %>
tvanfosson
fuente
1
¿Qué pasa si realmente insistes en el valor de 0? Si el valor es nulo / una cadena vacía, puede causar problemas con el enlace del modelo.
Kjensen
2
Si lo espera como un int, entonces usaría int? y aún déjelo nulo si no se ha realizado ninguna selección.
tvanfosson
13
El problema con esta solución es que pierde el artículo seleccionado.
37Stars
1
@JesseWebb Sospecho que solo necesita asegurarse de que está usando una firma que incluye la etiqueta de opción, msdn.microsoft.com/en-us/library/ee703567.aspx , @Html.DropDownListFor( m => m.MenuSelection, (IEnumerable<SelectListItem>)ViewBag.Menu, "Select One", null )por ejemplo, incluyendo el nulo htmlAttributespara evitar confusión con la firma que toma una expresión, la enumeración del menú y un objeto (htmlAttributes).
tvanfosson
1
@tvanfosson - Gracias por aclarar. Intenté usarlo con un tipo Complex como el tipo de IEnumerable en SelectList. Tuve que especificar el dataValueFieldy el dataTestFieldque hizo que esto no funcionara al agregar un valor optionLabel. Probablemente podría haber funcionado con un poco más de esfuerzo, pero solo utilicé una de las soluciones alternativas. ¡Gracias de todos modos!
Jesse Webb
82

Logré que esto funcionara rellenando un SelectListItem, convirtiéndolo en una lista y agregando un valor en el índice 0.

List<SelectListItem> items = new SelectList(CurrentViewSetups, "SetupId", "SetupName", setupid).ToList(); 
items.Insert(0, (new SelectListItem { Text = "[None]", Value = "0" }));
ViewData["SetupsSelectList"] = items;
davewilliams459
fuente
Recomiendo usar la sobrecarga de optionLabel en HtmlHelper -> @ Html.DropDownListFor
2b77bee6-5445-4c77-b1eb-4df3e5
17

Esto es posible.

//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
fuente
Recomiendo usar la sobrecarga de optionLabel en HtmlHelper -> @ Html.DropDownListFor
2b77bee6-5445-4c77-b1eb-4df3e5
13

Me gustó la respuesta de @ AshOoO, pero al igual que @Rajan Rawal, necesitaba preservar el estado del elemento seleccionado, si corresponde. Así que agregué mi personalización a su método.AddFirstItem()

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);
}
Perro H
fuente
Recomiendo usar la sobrecarga de optionLabel en 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");
        }

Esto debería hacer lo que necesita, simplemente envíe su lista de selección y devolverá una lista de selección con un elemento en el índice 0

Puede personalizar el texto, el valor o incluso el índice del elemento que necesita insertar

AshOoO
fuente
¿Qué pasa si tengo algunos valores seleccionados y quiero conservarlos?
Rajan Rawal
Recomiendo usar la sobrecarga de optionLabel en HtmlHelper -> @ Html.DropDownListFor
2b77bee6-5445-4c77-b1eb-4df3e5
5

Aquí el ayudante HTML para ti

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;
}
oculto
fuente
3

El método .ToList (). Insert (..) coloca un elemento en su Lista. Se puede especificar cualquier posición. Después de ToList, simplemente agregue .Insert (0, "- - Primer elemento - -")

Tu codigo

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

Nuevo código

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

Puede que no suene muy elegante, pero suelo hacer algo como esto:

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

De acuerdo, me gusta el código limpio, así que hice de este un método de extensión

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
    }
}

Uso (por ejemplo):

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
fuente
1

Como esta opción puede necesitar de muchas maneras diferentes, llegué a la conclusión de desarrollar un objeto para que pueda ser utilizado en diferentes escenarios y en proyectos futuros.

primero agregue esta clase a su proyecto

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 });                    
    }
}

Ahora en Acción del controlador puedes hacer esto

    // 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"));

Y finalmente en Ver codificarás así.

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

Una solución alternativa es usar la respuesta de @ tvanfosson (la respuesta seleccionada) y usar JQuery (o Javascript) para establecer el valor de la opción en 0:

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

Espero que esto ayude.

chico lógico
fuente
0

Pruebe algo como el siguiente código:

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
fuente
-5

No lo sé si alguien más tiene una mejor opción ...

<% 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=" "})%>
<% }>
New2this
fuente