Bagaimana saya bisa membuat SelectList ASP.NET MVC ini berfungsi?

126

Saya membuat selectList di controller saya, untuk ditampilkan dalam tampilan.

Saya mencoba membuatnya dengan cepat, agak .. seperti ini ...

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

Mengkompilasi, tetapi hasilnya buruk ...

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

Perhatikan bagaimana tidak ada item yang dipilih?

Bagaimana saya bisa memperbaikinya ??

Murni
sumber
1
Enam jawaban ... satu diunggulkan ... tidak ada upvotes: / Saya akan memberikannya +1
giat

Jawaban:

128

Beginilah cara saya melakukannya

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

Sekilas saya tidak yakin saya tahu apa yang Anda cari ...

mhenrixon
sumber
2
Terima kasih ini membantu saya memecahkan masalah ini.
Cadoo
6
Tidak memperbaiki masalah item yang dipilih tetapi itu adalah cara yang bagus untuk menghindari string sihir untuk daftar terpilih! Cheers
Alan Christensen
11
Untuk memperbaiki masalah item yang dipilih, tambahkan kode berikut: di SelectList sList = new SelectList(selectList, "Text", "Value", selected);mana selectedpelanggan yang dipilih saat ini
jao
68

Saya menggunakan metode ekstensi:

pemakaian

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

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

dengan

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;
    }
}
Thomas Stock
sumber
bagus. Saya telah menambahkan Func yang dipilih, opsi DefaultValue dan kelebihan kedua tanpa menentukan default dan ini berfungsi. Ngomong-ngomong jika Anda ingin membuat jenis pengembalian IEnumerable <SelectListItem> Anda dapat menggunakan sintaks pengembalian hasil untuk membuat ini terlihat sangat bersih
Chris Meek
48

Menggunakan konstruktor yang menerima items, dataValueField, dataTextField, selectedValuesebagai parameter:

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

Lalu menurut Anda:

<%=Html.DropDownList("myList") %>
Çağdaş Tekin
sumber
3
teman baik :) saya suka! Saya mencoba untuk melakukan ini .. tetapi saya tidak bisa mendapatkan bagian. Pilih (..) .. bagus :) Saya akan mencobanya di rumah, nanti :)
Pure.Krome
1
Heya Cagdas. berfungsi dengan baik, kecuali bidang yang dipilih tidak dipilih. ada ide? Apakah ini bug dalam hal-hal MVC?
Pure.Krome
2
Item yang dipilih berfungsi ketika Anda menambahkan item SelectList ke objek ViewData (seperti pada ViewData ["myList"] = SelectList baru ..) dan kemudian merendernya dengan <% = Html.DropDownList ("myList")%>. Saya tidak bisa mendapatkan item yang dipilih untuk bekerja tanpa melakukannya dengan cara ini. Aneh.
Çağdaş Tekin
@Cagdas - hai lagi Bung .. saya masih belum menemukan ini :( Apa ini tentang ViewData ??? Saya punya ViewData yang sangat diketik dengan properti miliknya sendiri .... ???
Pure.Krome
@ Pure.Krome - Saya mengambil properti itu dari contoh Anda dalam pertanyaan. Sekarang saya sedang mengedit contoh kode. Silakan lihat edit saya dalam beberapa detik.
Çağdaş Tekin
19

Membangun jawaban Thomas Stock, saya menciptakan ToSelectListmetode kelebihan ini :

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

Di controller Anda, Anda dapat melakukan hal berikut:

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

Dan akhirnya di View Anda, masukkan:

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

Ini akan menghasilkan output yang diinginkan - tentu saja, Anda dapat meninggalkan "(Select one)"optionLabel di atas jika Anda tidak ingin item kosong pertama:

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

Pembaruan: Daftar kode yang direvisi dapat ditemukan di sini dengan komentar XML.

JustinStolle
sumber
13

Masalahnya adalah, SelectList berfungsi seperti yang dirancang. Bug ada dalam desain. Anda dapat mengatur Properti Terpilih di SelectedItem, tetapi ini akan sepenuhnya diabaikan, jika Anda melintasi daftar dengan GetEnumerator () (atau jika Mvc melakukannya untuk Anda). Mvc akan membuat SelectListItems baru sebagai gantinya.

Anda harus menggunakan ctor SelectList dengan SelectListItem [], Teks-Nama, Nama-Nilai dan SelectedValue. Berhati-hatilah untuk lulus sebagai SelectedValue VALUE dari SelectListItem, yang ingin Anda pilih, bukan SelectListItem itu sendiri! Contoh:

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

(tidak diuji ini, tapi saya punya masalah yang sama)

maka opsi ke-2 akan mendapatkan atribut yang dipilih = "terpilih". Itu tampak seperti DataSets lama yang bagus ;-)

Goding Coding
sumber
11

Ini sebuah opsi:

myViewData.PageOptionsDropDown = new[] 
{
 new SelectListItem { Text = "10", Value = "10" },
 new SelectListItem { Text = "15", Value = "15", Selected = true }
 new SelectListItem { Text = "25", Value = "25" },
 new SelectListItem { Text = "50", Value = "50" },
 new SelectListItem { Text = "100", Value = "100" },
 new SelectListItem { Text = "1000", Value = "1000" },
}
murki
sumber
SelectListItem baru {Selected = true, Text = "15", Value = "15"} untuk nilai yang dipilih.
Cadoo
oops, yeah, lupa untuk menyertakan 'Dipilih' properti, terima kasih Cadoo =)
murki
10

Jika hanya itu yang ingin Anda lakukan, cukup deklarasikan array sebagai string yang memperbaiki masalah item yang dipilih:

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

Sangat mudah untuk membuat SelectList dan SelectedValue bekerja bersama, bahkan jika properti Anda bukan objek sederhana seperti Int, String, atau nilai Double.

Contoh:

Dengan asumsi objek Wilayah kami adalah sesuatu seperti ini:

public class Region {
     public Guid ID { get; set; }
     public Guid Name { get; set; }
}

Dan model tampilan Anda adalah seperti:

public class ContactViewModel {
     public DateTime Date { get; set; }
     public Region Region { get; set; }
     public List<Region> Regions { get; set; }
}

Anda dapat memiliki kode di bawah ini:

@Html.DropDownListFor(x => x.Region, new SelectList(Model.Regions, "ID", "Name")) 

Hanya jika Anda mengganti metode ToString objek Region ke sesuatu seperti:

public class Region {
     public Guid ID { get; set; }
     public Guid Name { get; set; }

     public override string ToString()
     {
         return ID.ToString();
     }
}

Ini memiliki jaminan 100% untuk bekerja.

Tapi saya benar-benar percaya cara terbaik untuk membuat SelectList 100% berfungsi di semua keadaan adalah dengan menggunakan metode Equals untuk menguji nilai properti DropDownList atau ListBox terhadap setiap item pada koleksi item.

ararog
sumber
5

Tampaknya jika Anda memiliki tampilan yang sangat diketik, Anda perlu mengubah ID dropdown sehingga BUKAN nama properti pada kelas yang diwarisi. Anda kemudian perlu memasukkan beberapa logika dalam metode edit (POST) Anda untuk menarik nilai yang dipilih dari FORMCollection dan menaruhnya di instance Anda sebelum melakukan perubahan Anda.

Ini tentu agak aneh, tetapi saya mencobanya dan berhasil.

Jadi, jika kelas Anda memiliki bidang yang disebut CountryId katakan, dan Anda menampilkan daftar nama negara, buat dropdown memiliki id CountryName daripada CountryId, maka dalam posting, Anda dapat melakukan sesuatu dengan Collection ["CountryName"] .


sumber
1
Ya, saya punya masalah yang sama. Cukup mengubah nama berhasil. Terima kasih!
davekaro
4

Saya memiliki masalah yang sama persis. Solusinya sederhana. Cukup ubah parameter "nama" yang diteruskan ke bantuan DropDownList ke sesuatu yang tidak cocok dengan properti apa pun yang ada di ViewModel Anda. baca lebih lanjut di sini: http://www.dotnetguy.co.uk/post/2009/06/25/net-mvc-selectlists-selected-value-does-not-get-set-set-in-the-viewview

Saya mengutip Dan Watson:

Dalam MVC jika tampilan diketik dengan kuat, opsi yang dipilih pada daftar pilih akan ditimpa dan properti opsi yang dipilih yang ditetapkan pada konstruktor tidak akan pernah mencapai tampilan dan pilihan pertama dalam dropdown akan dipilih sebagai gantinya (mengapa masih sedikit misteri) .

Bersulang!

cleftheris
sumber
3

Semua jawaban ini tampak hebat, tetapi tampaknya bahwa pengontrol sedang mempersiapkan data untuk Tampilan dalam format terstruktur yang terkenal vs. membiarkan tampilan hanya mengulangi IEnumerable <> yang dikirimkan melalui model dan membangun daftar pilih standar kemudian biarkan DefaultModelBinder mengirimkan item yang dipilih kembali kepada Anda melalui parameter tindakan. Ya, tidak, mengapa tidak? Pemisahan masalah, ya? Tampaknya aneh memiliki controller untuk membangun sesuatu sehingga UI dan Lihat spesifik.


sumber
3

Sederhana:

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

Saya hanya menjalankannya seperti ini dan tidak punya masalah,

public class myViewDataObj
    {
        public SelectList PageOptionsDropDown { get; set; }
    }

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

            ViewData["myList"] = myViewData.PageOptionsDropDown;
            return View();
        }

dan

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

itu juga berfungsi jika Anda melakukan ini,

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

            ViewData["myListValues"] = myViewData.PageOptionsDropDown;
            ViewData["myList"] = "15";
            return View();
        }

dan

<%=Html.DropDownList("myList",(IEnumerable<SelectListItem>)ViewData["myListValues"]) %>
Tony Borf
sumber
1

Menggunakan contoh Anda ini berhasil bagi saya:

pengontrol:

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

melihat:

<%= Html.DropDownList("PageOptionsDropDown")%>
Cadoo
sumber
Ya itu juga bekerja untuk saya. Dalam kasus saya, daftar adalah objek Model Entitas. Pengendali: ViewData ["Categories"] = SelectList baru (db.Categories.ToList (), "CategoryId", "CategoryName", "15"); Lihat: Html.DropDownList ("CategoryId", (SelectList) ViewData ["Kategori"], "--select--")
Junior Mayhé
1
MonthRepository monthRepository = new MonthRepository();
IQueryable<MonthEntity> entities = monthRepository.GetAllMonth();
List<MonthEntity> monthEntities = new List<MonthEntity>();

foreach(var r in entities)
{
    monthEntities.Add(r);
}

ViewData["Month"] = new SelectList(monthEntities, "MonthID", "Month", "Mars");
Kaktus
sumber
1

Saya melakukannya seperti ini:

List<SelectListItem> list = new List<SelectListItem>{
new SelectListItem {Selected = true, Text = "Select", Value = "0"},
new SelectListItem {Selected = true, Text = "1", Value = "1"},
new SelectListItem {Selected = true, Text = "2", Value = "2"}
};
return list.ToArray();

ToArray () menangani masalah.

femseks
sumber
1

Jika Anda ingin mengirimkan beberapa teks acak ke DropDownList Anda, misalnya - Pilih - Anda dapat dengan mudah melakukan ini menggunakan kode ini:

@Html.DropDownListFor(x => x.CategoryId, new SelectList(Model.Categories, "Id", "Name"), "--Select--", new { @class = "form-control" })
Münich
sumber
0

Mungkin Anda memiliki beberapa ambiguitas dalam ViewData Anda:

Lihatlah di sini

KP.
sumber
0

nilai yang dipilih dalam model mengambil keuntungan alih-alih item default. (Saya setuju saya tidak membaca semua posting)

Daniel
sumber
0

Saya tidak ingat bagaimana pengaturan mvc 1, tetapi tampaknya ia ingin daftar pilih bernama sama dengan bidang miliknya juga ...

Apa yang saya temukan, seperti yang dikatakan seseorang di atas, adalah bahwa daftar pilih saya tidak berfungsi di mvc2 ketika ViewData yang mereka kirim sama dengan bidang yang sama.

Sebagai contoh:

<%= Html.DropDownListFor((model => model.ForID), (SelectList)ViewData["ForName"]) %>

bekerja kapan

<%= Html.DropDownListFor((model => model.ForID), (SelectList)ViewData["ForID"]) %>

tidak berfungsi karena nama ViewData "ForID" dinamai sama dengan bidang tempat ia bekerja

Menandai
sumber
0

Penjelasan yang mungkin adalah bahwa nilai daftar pilih yang Anda ikat bukan string.

Jadi dalam contoh itu, apakah parameter 'PageOptionsDropDown' adalah string dalam model Anda? Karena jika tidak maka nilai yang dipilih dalam daftar tidak akan ditampilkan.

FruitDealer
sumber
0

Jika Anda melihat dalam kode sumber untuk MVC 2 di metode ekstensi Html.DropDownList, itu tidak pernah memeriksa properti SelectList kelas SelectedValue. Itu hanya akan mencoba untuk mencocokkan dengan Model Anda.

Semua yang di atas adalah semua variasi pada tema, yaitu bagaimana Anda mengirim banyak data ke tampilan untuk daftar drop-down & mereka semua sama baiknya satu sama lain (lebih atau kurang).

Masalahnya ada di tampilan. Baik buat metode ekstensi DropDownList Anda sendiri yang menghargai nilai pilih yang Anda atur, atau lakukan iterasi dengan tangan. Mana yang paling cocok untuk Anda.

Simon Halsey
sumber
@ Franz Antesberger mengatakan hal yang sama.
Simon Halsey
0

Jika Anda memiliki koleksi dalam model Anda dan Tampilan Anda sangat diketik, beberapa variasi ini akan berfungsi:

@Html.DropDownListFor(x => x.RegionID, 
    new SelectList(Model.Regions,"RegionID", "RegionName", Model.RegionID))

-atau-

@Html.DropDownList("RegionID", 
    new SelectList(Model.Regions, "RegionID", "RegionName", Model.RegionID))
Menandai
sumber