128 votes

Comment puis-je faire fonctionner cette SelectList ASP.NET MVC ?

Je crée une liste de sélection dans mon contrôleur, pour l'afficher dans la vue.

J'essaie de le créer à la volée, une sorte de chose ... comme ça ...

myViewData.PageOptionsDropDown = 
   new SelectList(new [] {"10", "15", "25", "50", "100", "1000"}, "15");

Il compile, mais la sortie est mauvaise...

<select id="PageOptionsDropDown" name="PageOptionsDropDown">
    <option>10</option>
    <option>15</option>
    <option>25</option>
    <option>50</option>
    <option>100</option>
    <option>1000</option>
</select>

Vous avez remarqué qu'aucun élément n'est sélectionné ?

Comment puis-je réparer cela ?

1 votes

Six réponses... une favorisée... pas de upvotes :/ Je lui donne un +1.

0 votes

128voto

mhenrixon Points 3178

C'est comme ça que je fais

IList<Customer> customers = repository.GetAll<Customer>();
IEnumerable<SelectListItem> selectList = 
    from c in customers
    select new SelectListItem
    {
        Selected = (c.CustomerID == invoice.CustomerID),
        Text = c.Name,
        Value = c.CustomerID.ToString()
    };

A première vue, je ne suis pas sûr de savoir ce que vous cherchez...

2 votes

Merci, cela m'a aidé à comprendre ce genre de choses.

6 votes

Cela ne résout pas le problème de l'élément sélectionné mais c'est un excellent moyen d'éviter les chaînes magiques pour les listes de sélection ! Merci à

11 votes

Pour résoudre le problème de l'élément sélectionné, ajoutez le code suivant : SelectList sList = new SelectList(selectList, "Text", "Value", selected); donde selected est le client sélectionné actuel

68voto

Thomas Stock Points 4165

J'utilise une méthode d'extension :

utilisation

var departmentItems = departments.ToSelectList(d => d.Code + 
                                               " - " + d.Description,
                                               d => d.Id.ToString(),
                                               " - ");

var functionItems = customerFunctions.ToSelectList(f => f.Description, 
                                                   f => f.Id.ToString(), 
                                                   " - ");

avec

public static class MCVExtentions
{
    public static List<SelectListItem> ToSelectList<T>(
        this IEnumerable<T> enumerable, 
        Func<T, string> text, 
        Func<T, string> value, 
        string defaultOption)
    {
        var items = enumerable.Select(f => new SelectListItem()
                                     {
                                         Text = text(f), 
                                         Value = value(f) 
                                     }).ToList();
        items.Insert(0, new SelectListItem()
                    {
                        Text = defaultOption, 
                        Value = "-1" 
                    });
        return items;
    }
}

0 votes

Agréable. J'ai ajouté un Func sélectionné, une option defaultValue et une deuxième surcharge sans aucune valeur par défaut à spécifier et cela fonctionne à merveille. Au fait, si vous voulez que le type de retour soit IEnumerable<SelectListItem>, vous pouvez utiliser la syntaxe yield return pour obtenir un résultat très propre.

48voto

çağdaş Points 10552

En utilisant le constructeur qui accepte items, dataValueField, dataTextField, selectedValue comme paramètres :

ViewData["myList"] = 
                new SelectList(new[] { "10", "15", "25", "50", "100", "1000" }
                .Select(x => new {value = x, text = x}), 
                "value", "text", "15");

Alors, à votre avis :

<%=Html.DropDownList("myList") %>

3 votes

Sympa mec :) j'aime bien ! j'ai essayé de faire ça mais je n'ai pas réussi à avoir la partie .Select(..) sympa :) Je vais l'essayer à la maison, plus tard :)

1 votes

Heya Cagdas. Cela fonctionne très bien, sauf que le champ sélectionné n'est pas sélectionné. Une idée ? Est-ce un bug dans le MVC ?

2 votes

Selected item fonctionne lorsque vous ajoutez l'élément SelectList dans l'objet ViewData (comme dans ViewData["myList"] = new SelectList ..) et que vous le rendez ensuite avec <%=Html.DropDownList("myList") %>. Je n'ai pas réussi à faire fonctionner l'élément sélectionné sans le faire de cette façon cependant. Bizarre.

20voto

JustinStolle Points 2129

En m'inspirant de la réponse de Thomas Stock, j'ai créé les fichiers surchargés suivants ToSelectList méthodes :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;

public static partial class Helpers
{
    public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<T> enumerable, Func<T, object> value, bool selectAll = false)
    {
        return enumerable.ToSelectList(value, value, selectAll);
    }

    public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<T> enumerable, Func<T, object> value, object selectedValue)
    {
        return enumerable.ToSelectList(value, value, new List<object>() { selectedValue });
    }

    public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<T> enumerable, Func<T, object> value, IEnumerable<object> selectedValues)
    {
        return enumerable.ToSelectList(value, value, selectedValues);
    }

    public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<T> enumerable, Func<T, object> value, Func<T, object> text, bool selectAll = false)
    {
        foreach (var f in enumerable.Where(x => x != null))
        {
            yield return new SelectListItem()
            {
                Value = value(f).ToString(),
                Text = text(f).ToString(),
                Selected = selectAll
            };
        }
    }

    public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<T> enumerable, Func<T, object> value, Func<T, object> text, object selectedValue)
    {
        return enumerable.ToSelectList(value, text, new List<object>() { selectedValue });
    }

    public static IEnumerable<SelectListItem> ToSelectList<T>(this IEnumerable<T> enumerable, Func<T, object> value, Func<T, object> text, IEnumerable<object> selectedValues)
    {
        var sel = selectedValues != null
            ? selectedValues.Where(x => x != null).ToList().ConvertAll<string>(x => x.ToString())
            : new List<string>();

        foreach (var f in enumerable.Where(x => x != null))
        {
            yield return new SelectListItem()
            {
                Value = value(f).ToString(),
                Text = text(f).ToString(),
                Selected = sel.Contains(value(f).ToString())
            };
        }
    }
}

Dans votre contrôleur, vous pourriez faire ce qui suit :

var pageOptions = new[] { "10", "15", "25", "50", "100", "1000" };
ViewBag.PageOptions = pageOptions.ToSelectList(o => o, "15" /*selectedValue*/);

Et enfin dans votre vue, mettez :

@Html.DropDownList("PageOptionsDropDown", ViewBag.PageOptions as IEnumerable<SelectListItem>, "(Select one)")

Vous obtiendrez le résultat escompté. Bien sûr, vous pouvez omettre l'élément "(Select one)" optionLabel ci-dessus si vous ne voulez pas le premier élément vide :

<select id="PageOptionsDropDown" name="PageOptionsDropDown">
<option value="">(Select one)</option>
<option value="10">10</option>
<option selected="selected" value="15">15</option>
<option value="25">25</option>
<option value="50">50</option>
<option value="100">100</option>
<option value="1000">1000</option>
</select>

Mise à jour : Une liste révisée des codes peut être trouvé ici avec des commentaires XML.

13voto

Le problème est que SelectList fonctionne comme prévu. L'erreur se situe au niveau de la conception. Vous pouvez définir la propriété Selected dans SelectedItem, mais cela sera complètement ignoré, si vous parcourez la liste avec GetEnumerator() (ou si Mvc le fait pour vous). Le Mvc créera de nouveaux SelectListItems à la place.

Vous devez utiliser le ctor SelectList avec le SelectListItem[], le Text-Name, le Value-Name et le SelectedValue. Faites attention à passer comme SelectedValue la VALEUR du SelectListItem que vous voulez sélectionner, pas le SelectListItem lui-même ! Exemple :

SelectList sl = new SelectList( new[]{
  new SelectListItem{ Text="one", Value="1"},
  new SelectListItem{ Text="two", Value="2"},
  new SelectListItem{ Text="three", Value="3"}
}, "Text", "Value", "2" );

(je n'ai pas testé cela, mais j'ai eu le même problème)

alors la deuxième option obtiendra l'attribut selected="selected". Cela ressemble aux bons vieux DataSets ;-)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X