50 votes

DropDownListFor dans EditorTemplate ne sélectionne pas la valeur

J'ai un modèle d'éditeur pour un objet personnalisé. À l'intérieur de ce modèle d'éditeur, j'utilise un couple d'aides DropDownListFor. Dans chacun d'eux, je spécifie une propriété de modèle unique (avec la valeur présélectionnée) et la liste de sélection contenant toutes les options de sélection.

Exemple :

<%=Html.DropDownListFor(m => m.DocumentCategoryType, Model.DocumentCategoryTypeList) %>

Je sais que les valeurs des options sont remplies (à partir de la source de visualisation) et que mon modèle est transmis avec la valeur ID correcte (DocumentCategoryType).

Lorsque la vue est rendue, il n'y a pas d'élément sélectionné dans ma liste déroulante et celle-ci prend donc par défaut la première valeur (non sélectionnée).

Quelqu'un a-t-il une idée ?

Gracias.

28voto

itsmecurtis Points 1815

Nous avons également résolu la solution en remplissant un nouveau fichier SelectList qui a les SelectListItem sélectionné, mais a créé cette méthode d'extension pour conserver l'appel à DropDownListFor un peu plus propre :

public static SelectList MakeSelection(this SelectList list, object selection)
{
    return new SelectList(list.Items, list.DataValueField, list.DataTextField, selection);
}

Alors votre DropDownListFor l'appel devient :

<%= Html.DropDownListFor(m => m.DocumentCategoryType, Model.DocumentCategoryTypeList.MakeSelection(Model.DocumentCategoryType)) %>

18voto

Russ Cam Points 58168

En parcourant le code source d'ASP.NET MVC 2, vous trouverez quelques solutions à ce problème. Essentiellement, tout SelectListItem dans le SelectList passée dans la méthode d'extension de l'aide qui a l'attribut Selected définie à true n'a pas d'influence sur la propriété <option> rendu avec l'élément selected appliqué à l'élément.

El selected l'attribut <option> est déterminée par

1) vérifier que la méthode d'extension de l'aide a reçu un fichier SelectList . Si cette valeur est nulle, le cadre recherche dans les données de vue une valeur correspondant à la clé qui est la propriété du modèle de vue pour laquelle vous souhaitez rendre la liste déroulante. Si la valeur est un SelectList ce qui sera utilisé pour rendre l <select> y compris en prenant toute valeur sélectionnée, tant que l'état du modèle pour la propriété du modèle est nul.

2) Si un SelectList a été transmis dans la méthode d'extension de l'aide et que l'état du modèle pour la propriété du modèle est nul, le cadre recherchera dans les données de vue une valeur par défaut, en utilisant le nom de la propriété du modèle comme clé. La valeur dans les données de vue est convertie en une chaîne de caractères et tout élément dans le champ SelectList transmises à la méthode d'extension de l'aide et dont la valeur (si aucune valeur n'est définie, le texte sera vérifié) correspond à la valeur par défaut auront l'attribut Selected définie à true, ce qui rendra une <option> avec l'attribut selected="selected" .

En mettant tout cela ensemble, je vois deux options plausibles pour qu'une option soit sélectionnée et que l'on utilise l'option fortement typée DropDownListFor :

En utilisant le modèle de vue suivant

public class CategoriesViewModel
{
    public string SelectedCategory { get; private set ; }
    public ICollection<string> Categories { get; private set; }

    public CategoriesViewModel(string selectedCategory, ICollection<string> categories)
    {
        SelectedCategory = selectedCategory;
        Categories = categories;
    }
}

Option 1

Définissez une valeur dans les ViewData du contrôleur qui rend votre vue, en fonction du nom de la propriété de la collection utilisée pour rendre la liste déroulante.

l'action du contrôleur

public class CategoriesController
{
    [HttpGet]
    public ViewResult Select()
    {
        /* some code that gets data from a datasource to populate the view model  */
        ICollection<string> categories = repository.getCategoriesForUser();
        string selectedCategory = repository.getUsersSelectedCategory();

        CategoriesViewModel model = new CategoriesViewModel(selectedCategory, categories);
        this.ViewData["Categories"] = selectedCategory;        

        return View(model);
    }

    [HttpPost]
    public ActionResult Select(CategoriesViewModel model)
    {
        /* some code that does something */
    }
}

et dans la vue fortement typée

<%: Html.DropDownListFor(m => m.Categories, Model.Categories.Select(c => new SelectListItem { Text = c, Value = c }), new { @class = "my-css-class" }) %>

Option 2

Rendre la liste déroulante en utilisant le nom de la propriété du ou des éléments sélectionnés

l'action du contrôleur

public class CategoriesController
{
    [HttpGet]
    public ViewResult Select()
    {
        /* some code that gets data from a datasource to populate the view model  */
        ICollection<string> categories = repository.getCategoriesForUser();
        string selectedCategory = repository.getUsersSelectedCategory();

        CategoriesViewModel model = new CategoriesViewModel(selectedCategory, categories);

        return View(model);
    }

    [HttpPost]
    public ActionResult Select(CategoriesViewModel model)
    {
        /* some code that does something */
    }
}

et dans la vue fortement typée

<%: Html.DropDownListFor(m => m.SelectedCategory, Model.Categories.Select(c => new SelectListItem { Text = c, Value = c }), new { @class = "my-css-class" }) %>

14voto

Alexander Taran Points 3907

C'est confirmé comme un bug @ aspnet.codeplex.com et ne se comporte de la sorte que pour les vues fortement typées.

Solution : remplissez votre SelectList dans le code de la vue.

comme

<%= Html.DropDown("DocumentCategoryType", new SelectList(Model.Categories,"id","Name",Model.SelectedCategory")) =>

6voto

kmehta Points 798

Beurk. J'ai fini par résoudre le problème comme ceci. J'espère que cela sera corrigé pour la RTM.

   <%if(Model!=null){ %>
        <%= Html.DropDownListFor(m => m.DocumentCategoryType, new SelectList(Model.DocumentCategoryTypeList,"Value","Text", Model.DocumentCategoryType))%>
        <%}else{%>
            <%=Html.DropDownListFor(m => m.DocumentCategoryType, Model.DocumentCategoryTypeList) %>
        <%}%>

1voto

Brett Allred Points 1993

Assurez-vous qu'une valeur est attribuée à m.DocumentCategoryType lorsque vous l'envoyez à la vue.

Généralement, cette valeur est réinitialisée lorsque vous effectuez un post back, il vous suffit donc de spécifier la valeur lorsque vous revenez à votre vue.

Lorsque vous créez une liste déroulante, vous devez lui transmettre deux valeurs. 1. C'est l'endroit où vous allez stocker la valeur sélectionnée 2. C'est la liste actuelle

Exemple

<%=Html.DropDownListFor(m => m.DocumentCategoryType, Model.DocumentCategoryTypeList) %>

J'ai fait l'erreur de donner la valeur True à l'élément Selected de la liste de sélection. Cela ne sert à rien. Au lieu de cela, attribuez une valeur à m.DocumentCategoryType dans votre contrôleur et cela fera la sélection pour vous.

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