C # DropDownList พร้อมพจนานุกรมเป็น DataSource


112

ฉันต้องการตั้งค่าDataTextFieldและDataValueFieldของDropdownlist(languageList) โดยใช้พจนานุกรม (รายการ) ของlanguageCod(en-gb) เป็นคีย์และชื่อภาษา (อังกฤษ) เป็นข้อความที่จะแสดง

รหัสที่เกี่ยวข้อง:

string[] languageCodsList= service.LanguagesAvailable();
Dictionary<string, string> list = 
                   new Dictionary<string, string>(languageCodsList.Length);

foreach (string cod in languageCodsList)
{
    CultureInfo cul = new CultureInfo(cod);
    list.Add(cod, cul.DisplayName);
}
languageList.DataSource = list;
languageList.DataBind();

ฉันจะตั้งค่าDataTextFieldและDataValueField?

คำตอบ:


205

เช่นเดียวกับที่คุณสามารถตั้งค่า DataTextField และ DataValueField ของ DropDownList โดยใช้ข้อความ "Key" และ "Value":

    Dictionary<string, string> list = new Dictionary<string, string>();
    list.Add("item 1", "Item 1");
    list.Add("item 2", "Item 2");
    list.Add("item 3", "Item 3");
    list.Add("item 4", "Item 4");

    ddl.DataSource = list;
    ddl.DataTextField = "Value";
    ddl.DataValueField = "Key";
    ddl.DataBind();

12
ฉันขอแนะนำให้ตั้งค่า TextField เป็น "key" และ ValueField เป็น Value ฉันคิดว่ามันง่ายกว่า
MGOwen

15
@MGOwen อาจดูเหมือนง่ายที่จะตั้งค่า DataValueField เป็น Value เนื่องจากมี "ค่า" ทั่วไป แต่จริงๆแล้วมันเป็นเรื่องที่ไม่สมเหตุสมผลในการใช้โครงสร้าง / การควบคุมข้อมูลเป็นประจำ สำหรับรายละเอียดเกี่ยวกับเรื่องนี้โปรดดูความคิดเห็นของฉันเกี่ยวกับคำตอบของ Jon Skeet
Dani

ฉันไม่เห็นรายการเพิ่มที่ใช้ 2 args .. อันเดียวที่ใช้อาร์กิวเมนต์เดียว นี่คือ winforms ??
ชม.

@hrh คุณอาจไม่ได้ใช้ a Dictionary<TKey, TValue>แต่อาจเป็นList<T>ไฟล์.
ดู

@Canavar ตั้งค่าฟิลด์ DataText เป็น "คีย์ - ค่า" ได้หรือไม่ .... ? ฉันจะทำมันได้อย่างไร.
Sravan Kumar

11

เมื่อมีการแจกแจงพจนานุกรมมันจะให้KeyValuePair<TKey,TValue>วัตถุ ... ดังนั้นคุณเพียงแค่ระบุ "ค่า" และ "คีย์" สำหรับDataTextFieldและDataValueFieldตามลำดับเพื่อเลือกคุณสมบัติค่า / คีย์

ขอบคุณความคิดเห็นของโจฉันอ่านคำถามซ้ำเพื่อให้สิ่งเหล่านี้ถูกต้อง โดยปกติฉันคาดหวังว่า "คีย์" ในพจนานุกรมจะเป็นข้อความที่ปรากฏและ "ค่า" เป็นค่าที่ดึงมา โค้ดตัวอย่างของคุณใช้ในทางกลับกัน หากคุณไม่ต้องการให้เป็นแบบนี้จริงๆคุณอาจต้องการพิจารณาเขียนโค้ดของคุณเป็น:

list.Add(cul.DisplayName, cod);

(จากนั้นเปลี่ยนการผูกเพื่อใช้ "คีย์" สำหรับDataTextFieldและ "ค่า" สำหรับDataValueFieldแน่นอน)

อันที่จริงฉันขอแนะนำว่าดูเหมือนว่าคุณต้องการรายการมากกว่าพจนานุกรมจริงๆคุณอาจต้องการพิจารณาใหม่โดยใช้พจนานุกรมในตอนแรก คุณสามารถใช้List<KeyValuePair<string, string>>:

string[] languageCodsList = service.LanguagesAvailable();
var list = new List<KeyValuePair<string, string>>();

foreach (string cod in languageCodsList)
{
    CultureInfo cul = new CultureInfo(cod);
    list.Add(new KeyValuePair<string, string>(cul.DisplayName, cod));
}

หรือใช้รายการCultureInfoค่าธรรมดา LINQ ทำให้สิ่งนี้ง่ายมาก:

var cultures = service.LanguagesAvailable()
                      .Select(language => new CultureInfo(language));
languageList.DataTextField = "DisplayName";
languageList.DataValueField = "Name";
languageList.DataSource = cultures;
languageList.DataBind();

หากคุณไม่ได้ใช้ LINQ คุณยังสามารถใช้ foreach loop ตามปกติได้:

List<CultureInfo> cultures = new List<CultureInfo>();
foreach (string cod in service.LanguagesAvailable())
{
    cultures.Add(new CultureInfo(cod));
}
languageList.DataTextField = "DisplayName";
languageList.DataValueField = "Name";
languageList.DataSource = cultures;
languageList.DataBind();

3
อันที่จริงสิ่งนี้ไม่ถูกต้อง - ดูความคิดเห็นของฉันเกี่ยวกับคำตอบที่ยอมรับ
Winston Smith

อ่าฉันอ่านคำถามผิด มันดูสับสนสำหรับฉันที่ใส่คำว่า "ผิด" ในพจนานุกรม จะแก้ไขคำตอบของฉัน
Jon Skeet

1
@JonSkeet สาเหตุของการเชื่อมโยง "ย้อนกลับ" คือข้อมูลที่จัดเก็บในพจนานุกรมเป็นคู่คีย์ / ค่าโดยปกติจะใช้คีย์ (ค่าการค้นหา) เป็นการเชื่อมโยงข้อมูล (เช่นสำหรับการอ้างอิงฐานข้อมูล) และในรายการแบบเลื่อนลง ซึ่งสอดคล้องกับ DataValueField นั่นคือค่าที่ส่งคืนของ POST ซึ่งจะบอกคุณเกี่ยวกับรายการที่เลือกมากกว่า DataTextField นั่นคือค่าที่แสดง (DropDownLists มีรูปแบบการตั้งชื่อที่ไม่ดี)
Dani

6

หาก DropDownList ถูกประกาศในหน้า aspx ของคุณและไม่อยู่ใน codebehind คุณสามารถทำได้เช่นนี้

ขอบ:

<asp:DropDownList ID="ddlStatus" runat="server" DataSource="<%# Statuses %>"
     DataValueField="Key" DataTextField="Value"></asp:DropDownList>

.aspx.cs:

protected void Page_Load(object sender, EventArgs e)
{
    ddlStatus.DataBind();
    // or use Page.DataBind() to bind everything
}

public Dictionary<int, string> Statuses
{
    get 
    {
        // do database/webservice lookup here to populate Dictionary
    }
};

upvoted เป็นที่น่าสังเกตว่านี่เป็นวัตถุฝั่งเซิร์ฟเวอร์ที่ต้องได้รับการประเมิน คุณไม่สามารถส่งแบบอินไลน์ได้โดยใช้ <% # syntax%> ไม่ว่าจะเป็น <script runat = "server"> หรือตามที่เห็นในตัวอย่างของ Matt ด้านบนก็แล้วแต่คุณ มันใช้งานได้จริง
Barry

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.