Adding SelectListItem manually to SelectList to use in DropDownListFor
Asked Answered
L

5

18

When I create a SelecList I wish to be able to add SelecListItem's manually and to do this I use this code:

List<SelectListItem> Provinces = new List<SelectListItem>();
Provinces.Add(new SelectListItem() { Text = "Northern Cape", Value = "NC" });
Provinces.Add(new SelectListItem() { Text = "Free State", Value = "FS" });
Provinces.Add(new SelectListItem() { Text = "Western Cape", Value = "WC" });

SelectList lstProvinces = new SelectList(Provinces);

Instead of this :

var lstProvinces = new SelectList(new[] { "Northern Cape", "Free State", "Western Cape" });

After I created the SelectList, I pass it to the DropDownListFor via the ViewBag :

Html.DropDownListFor(m => m.StartPointProvince, (SelectList)ViewBag.Provinces)

However when I create the SelectList using the first method, it doesn't work - It adds the 3 values to the dropdown list, but all the values display as: Code *screenshot of output

However when I use the second method, it works fine. I wish to use the first method because i want to be able to specify the Text AND value of each item.

Lisettelisha answered 25/4, 2015 at 19:8 Comment(1)
Just use @Html.DropDownListFor(m => m.StartPointProvince, (IEnumerable<SelectListItem>)ViewBag.Provinces) - omit SelectList lstProvinces = new SelectList(Provinces);. DropDownListFor() accepts IEnumerable<SelectListItem> for the second parameter so its a bit pointless to create a SelectList (which is IEnumerable<SelectListItem>), and if you did it would need to be new SelectList(Provinces, "Value", "Text"); but this is just unnecessay overheadReadable
B
35

The problem is that SelectList(IEnumerable) constructor doesn't accept SelectListItem's (at least not as SelectListItem to add to its Items collection). It simply accepts collection of some arbitrary objects that will be used to generate completely unrelated internal SelectListItems collection.

If you want, you can use SelectList(IEnumerable, string, string) constructor in such way:

List<SelectListItem> Provinces = new List<SelectListItem>();
Provinces.Add(new SelectListItem() { Text = "Northern Cape", Value = "NC" });
Provinces.Add(new SelectListItem() { Text = "Free State", Value = "FS" });
Provinces.Add(new SelectListItem() { Text = "Western Cape", Value = "WC" });

this.ViewBag.Provinces = new SelectList(Provinces, "Value", "Text");

It will work. But it is unnecessary, because you create complex SelectListItem items that won't be used by the SelectList - it will just treat them as any other data object.

In the same way you can just use some other simpler class in place of SelectListItem:

public class SelectListModel
{
    public String Text { get; set; }
    public String Value { get; set; }
}

...
Provinces.Add(new SelectListModel() { Text = "Northern Cape", Value = "NC" });
Beriberi answered 25/4, 2015 at 19:27 Comment(3)
+1 for for pointing out that SelectListItem is needlessly complex in this scenario. I too was creating List<SelectListItem> because I thought it wasteful to create a custom SelectOption class, but now I see that SelectListItem is a more complex object and that it makes more sense to use simple custom class with no behaviourPhosphine
It works perfectly, is there a way how i can set selected value in this ?Introduce
@irshadjm #16599012Beriberi
B
11

Use DropDownList and name it the same as the model's property name. Mine is "ItemType"

     @Html.LabelFor(model => model.ItemType, new { @class = "control-label" })
     @Html.DropDownList("ItemType", (IEnumerable<SelectListItem>)ViewBag.ItemTypes, new { @class = "form-control" })
     @Html.ValidationMessageFor(model => model.ItemType, null, new { @class = "text-danger" })

        var types = new List<SelectListItem>();
        types.Add(new SelectListItem() { Text = "Select...", Value = string.Empty });
        types.Add(new SelectListItem() { Text = "OTC", Value = "0" });
        types.Add(new SelectListItem() { Text = "Generic", Value = "1" });
        types.Add(new SelectListItem() { Text = "Brand", Value = "2" });
        types.Add(new SelectListItem() { Text = "Non-Merchandise", Value = "9" });

        ViewBag.ItemTypes = types;

    [Required(ErrorMessage = "Item Type is required")]
    public Int32 ItemType { get; set; }
Baines answered 7/3, 2016 at 12:45 Comment(0)
M
6

you can change your code from

SelectList lstProvinces = new SelectList(Provinces);

to

SelectList lstProvinces = new SelectList(Provinces, "Value", "Text");

and it will display provinces correctly.

Mounts answered 12/10, 2017 at 23:49 Comment(0)
E
0

You do not need using SelectList.
Instead, put List<SelectListItem> Provinces into ViewBag and return ViewBag. Then on the View put:

@Html.DropDownList("Dropwonlist", (IEnumerable<SelectListItem>)ViewBag.YourData)
Electrostriction answered 1/1, 2021 at 16:23 Comment(0)
R
0

Considering the number of views on this topic, I thought it might help others in giving some further examples of which the option you chose depends on the desired contents of the select list.

I usually prefer to keep the assignment of select dropdown options in a seperate class which is more manageble when creating longer lists, it's also handy to use the same class of optons for more common applications across the app.

C# Class

public class CustomFormsSelectDropdownParams
{
    public static IEnumerable<SelectListItem> Example1ItemWidth { get; private set; }
    public static IEnumerable<SelectListItem> Example2ItemWidth { get; private set; }
    public static List<SelectListItem> Example3ItemWidth { get; private set; }

    static CustomFormsSelectDropdownParams()
    {
        // ---------
        // Exmaple 1
        // ---------
        // This is OK if you only have a
        // relatively small amount of options to write.
        Example1ItemWidth = new SelectListItem[]
        {
            // First item different to the remaining range.
            new SelectListItem ("100%", "100%"), 
            new SelectListItem ("5em", "5em"),
            new SelectListItem ("6em", "6em"),
            new SelectListItem ("7em", "7em"),
            new SelectListItem ("8em", "8em"),
            new SelectListItem ("9em", "9em"),
            new SelectListItem ("10em", "10em")
        };

        // ---------
        // Exmaple 2
        // ---------
        // This is more practical if you have a large amount of options.
        // NOTE: using this example doesnt allow us to insert any options
        // that are different from the rest, so limited use cases may apply.
        Example2ItemWidth = Enumerable.Range(1, 200).Select(x => new SelectListItem
        {
            Value = x.ToString() + "em",
            Text = x.ToString() + "em",
        });

        // ---------
        // Exmaple 3
        // ---------
        // This is more practical if you have a large amount of options.
        // This example also allows us to add an option that is a different
        // to the remaining options in the loop.

        // Our first item is bespoke so created seperately.
        var firstDefaultItem = new SelectListItem("100%", "100%");
        // Provides a range between 10 --> 200em
        var remainingItems = Enumerable.Range(10, 191).Select(x => new SelectListItem
        {
            Value = x.ToString() + "em",
            Text = x.ToString() + "em",
        });

        Example3ItemWidth = new List<SelectListItem>();
        // Add out first bespoke item.
        Example3ItemWidth!.Add(firstDefaultItem);
        // Add the remaining items in a loop.
        foreach (var item in remainingItems)
        {
            Example3ItemWidth.Add(new SelectListItem(item.Text, item.Value));
        }
    }
}

Sample HTML Code:

<div class="container-fluid">
    <div class="row">
        <div class="mb-3 col-3" >
            <label class="form-label">Example 1</label>
            <select class="form-select" asp-items="Classes.CustomForms.CustomFormsSelectDropdownParams.Example1ItemWidth"></select>
        </div>
    </div>
    <div class="row">
        <div class="mb-3 col-3" >
            <label class="form-label">Example 2</label>
            <select class="form-select" asp-items="Classes.CustomForms.CustomFormsSelectDropdownParams.Example2ItemWidth"></select>
        </div>
    </div>
    <div class="row">
        <div class="mb-3 col-3" >
            <label class="form-label">Example 3</label>
            <select class="form-select" asp-items="Classes.CustomForms.CustomFormsSelectDropdownParams.Example3ItemWidth"></select>
        </div>
    </div>
</div>

All three select dropdowns on the page:

enter image description here

Example 1:

enter image description here

Example 2:

enter image description here

Example 3:

enter image description here

Example 3 was the one that had niggled me for a while, I wasnt sure how to create an select options list as well as adding some other bespoke options at the same time. If i need to to add some more additional besoke options then I would simply add them in what ever order I need, either before the loop, after or in between multiple loops.

Reader answered 31/12, 2022 at 15:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.