ความแตกต่างระหว่าง SelectedItem, SelectedValue และ SelectedValuePath


352

ความแตกต่างระหว่างสิ่งต่อไปนี้คืออะไร:

คุณสมบัติการพึ่งพาเหล่านี้ทั้งหมดถูกกำหนดในคลาสSelector ฉันมักจะสับสนSelectedItemกับSelectedValueและกับSelectedValueSelectedValuePath

ผมอยากจะทราบความแตกต่างระหว่างพวกเขาและเมื่อเราจะใช้พวกเขาโดยเฉพาะอย่างยิ่งและSelectedValue SelectedValuePathโปรดอธิบายการใช้ของพวกเขาด้วยตัวอย่างง่ายๆ


3
Bea มีโพสต์บล็อกพร้อมคำอธิบายและโค้ดตัวอย่างที่คุณสามารถดาวน์โหลดได้ ... bea.stollnitz.com/blog/?p=9
Aaron McIver

2
ซ้ำได้ของ [สับสนกับ wpf ComboBox DisplayMemberPath, SelectedValue และ SelectedValuePath] ( stackoverflow.com/questions/3797034/… )

คำตอบ:


552

ชื่อของพวกเขาอาจสับสนเล็กน้อย :) นี่คือบทสรุป:

  • SelectedItemคุณสมบัติส่งกลับวัตถุทั้งที่รายการของคุณถูกผูกไว้กับ ดังนั้นสมมติว่าคุณได้ผูกรายการไว้กับชุดของCategoryวัตถุ (กับแต่ละหมวดหมู่วัตถุที่มีคุณสมบัติชื่อและรหัส) เช่น. ObservableCollection<Category>. SelectedItemอสังหาริมทรัพย์จะกลับมาให้คุณเลือกในปัจจุบันCategoryวัตถุ เพื่อจุดประสงค์ในการรวมสิ่งนี้ไม่ใช่สิ่งที่คุณต้องการเสมอไปเนื่องจากช่วยให้คุณสามารถผูกวัตถุประเภททั้งหมดกับคุณสมบัติที่รายการถูกผูกไว้ไม่ใช่ค่าของคุณสมบัติเดี่ยวบนวัตถุประเภทนั้น (เช่นIDคุณสมบัติ )

  • ดังนั้นเราจึงมีคุณสมบัติSelectedValuePathและคุณสมบัติSelectedValueเป็นวิธีการอื่นในการผูก (คุณใช้ร่วมกับอีกรายการหนึ่ง) สมมติว่าคุณมีProductวัตถุที่มุมมองของคุณถูกผูกไว้กับ (ด้วยคุณสมบัติสำหรับสิ่งต่าง ๆ เช่นชื่อผลิตภัณฑ์น้ำหนัก ฯลฯ ) สมมติว่าคุณมีCategoryIDคุณสมบัติบนวัตถุผลิตภัณฑ์นั้นและคุณต้องการให้ผู้ใช้สามารถเลือกหมวดหมู่สำหรับผลิตภัณฑ์จากรายการหมวดหมู่ คุณต้องมีคุณสมบัติ ID ของวัตถุประเภทเพื่อกำหนดให้กับCategoryIDคุณสมบัติบนวัตถุผลิตภัณฑ์ นี่คือที่SelectedValuePathและSelectedValueคุณสมบัติเข้ามาคุณระบุว่าคุณสมบัติ ID บนวัตถุประเภทควรกำหนดให้กับคุณสมบัติบนวัตถุผลิตภัณฑ์ที่รายการถูกผูกไว้กับการใช้SelectedValuePath='ID'งานแล้วผูกSelectedValueคุณสมบัติกับคุณสมบัติใน DataContext (เช่นผลิตภัณฑ์)

ตัวอย่างด้านล่างแสดงให้เห็นถึงสิ่งนี้ เรามี ComboBox ที่ผูกพันกับรายการหมวดหมู่ (ผ่าน ItemsSource) เรากำลังเชื่อมโยงคุณสมบัติ CategoryID บนผลิตภัณฑ์เป็นค่าที่เลือก (โดยใช้คุณสมบัติ SelectedValue) เราเกี่ยวข้องกับคุณสมบัติ ID ของหมวดหมู่ผ่านคุณสมบัติ SelectedValuePath และเรากำลังพูดว่าแสดงเฉพาะชื่อคุณสมบัติใน ComboBox ด้วยคุณสมบัติ DisplayMemberPath)

<ComboBox ItemsSource="{Binding Categories}" 
          SelectedValue="{Binding CategoryID, Mode=TwoWay}" 
          SelectedValuePath="ID" 
          DisplayMemberPath="Name" />
public class Category
{
    public int ID { get; set; }
    public string Name { get; set; }
}

public class Product
{
    public int CategoryID { get; set; }
}

มันค่อนข้างสับสนเล็กน้อยในตอนแรก แต่หวังว่านี่จะทำให้ชัดเจนขึ้น ... :)

คริส


8
ขอบคุณสำหรับคำอธิบาย คุณเป็นคนเดียวกับที่เขียนหนังสือเกี่ยวกับ Silverlight หรือไม่? ฉันไม่เชื่อว่าฉันกำลังพูดกับคุณ : -) ... ฉันกำลังอ่านหนังสือเล่มนี้ทุกวัน เป็นงานที่ยอดเยี่ยมจริงๆ :-)
Nawaz

22
ใช่นั่นคือฉัน :) ฉันแขวนส่วนที่นี่เหล่านี้เพื่อตอบคำถามเมื่อฉันสามารถ ดีใจที่คุณเพลิดเพลินกับหนังสือ :) เมื่อคุณได้รับหนังสือคุณจะพบข้อมูลเพิ่มเติมเกี่ยวกับหัวข้อนี้ในหน้า 69-70 และหน้า 204
Chris Anderson

8
+1 100 คุณครับเป็นเทพเจ้าทองคำในหมู่มนุษย์ที่มีจำนวนน้อยกว่า ขอพระเจ้าอวยพรคุณและทุกคนที่แล่นเรือในตัวคุณ :) อย่างจริงจังฉันเพิ่งใช้เวลาสองชั่วโมงพยายามที่จะคิดออกว่า - ขอบคุณ!
TarkaDaal

1
@Chris Anderson: ถ้าวัตถุผลิตภัณฑ์มีคุณสมบัติหมวดหมู่ (ประเภทประเภท) แทนที่จะเป็น CategoryID ฉันจะอัปเดตคุณสมบัติหมวดหมู่นี้เมื่อเปลี่ยน ComboBox ผ่านการเชื่อมโยงได้อย่างไร
Lucifer

2
@Lucifer: ในกรณีนี้คุณจะใช้คุณสมบัติ SelectedItem เช่นนั้น: <ComboBox ItemsSource = "{หมวดหมู่การผูก}" SelectedItem = "{หมวดหมู่การผูก, โหมด = TwoWay}" /> หวังว่านี่จะช่วยได้
Chris Anderson

69

หากต้องการตอบแนวคิดรวบยอดให้มากขึ้น:

SelectedValuePathกำหนดซึ่งทรัพย์สิน (ตามชื่อของมัน) ของวัตถุที่ถูกผูกไว้กับกล่องรายการของที่จะนำมาใช้เป็นของรายการItemsSourceSelectedValue

ตัวอย่างเช่นถ้ากล่องรายการของคุณถูกผูกไว้กับคอลเลกชันของPersonวัตถุแต่ละที่มีName, AgeและGenderคุณสมบัติSelectedValuePath=Nameจะทำให้คุณค่าของการเลือกPersonของสถานที่ให้บริการที่จะได้รับกลับมาในNameSelectedValue

โปรดทราบว่าถ้าคุณแทนที่ ControlTemplate ของกล่องรายการ (หรือใช้สไตล์) ที่ระบุคุณสมบัติที่ควรแสดงSelectedValuePathจะไม่สามารถใช้งานได้

SelectedItemในขณะเดียวกันส่งคืนPersonวัตถุทั้งหมดที่เลือกในปัจจุบัน

(นี่คือตัวอย่างเพิ่มเติมจาก MSDNโดยใช้ TreeView)

อัปเดต:ตามที่ @Joe ชี้แจงคุณสมบัติ DisplayMemberPath ไม่เกี่ยวข้องกับคุณสมบัติ * ที่เลือก คำอธิบายที่เหมาะสมดังต่อไปนี้:

โปรดทราบว่าค่าเหล่านี้จะแตกต่างจากDisplayMemberPath(ซึ่งกำหนดไว้ใน ItemsControl ไม่ใช่ตัวเลือก) แต่คุณสมบัตินั้นมีลักษณะการทำงานที่คล้ายคลึงกับSelectedValuePath: ในกรณีที่ไม่มีสไตล์ / แม่แบบมันจะระบุคุณสมบัติของวัตถุที่ผูกกับรายการที่ควรใช้ การเป็นตัวแทนสตริง


8

SelectedItemobjectเป็น SelectedValueและSelectedValuePathมีstrings

ตัวอย่างเช่นการใช้กล่องรายการ:

ถ้าคุณบอกว่าให้ฉันlistbox1.SelectedValueมันจะส่งคืนข้อความของรายการที่เลือกในปัจจุบัน

string value = listbox1.SelectedValue;

ถ้าคุณบอกว่าให้ฉันlistbox1.SelectedItemมันจะให้คุณวัตถุทั้งหมด

ListItem item = listbox1.SelectedItem;
string value = item.value;

3
SelectedValueนอกจากนี้ยังเป็นและไม่ได้เป็นobject stringกรุณาดูที่นี่
john_m

5

แรงบันดาลใจจากคำถามนี้ผมได้เขียนบล็อกพร้อมกับรหัส snippet ที่นี่ ด้านล่างนี้เป็นข้อความที่ตัดตอนมาจากบล็อก

SelectedItem - รายการที่เลือกช่วยผูกค่าจริงจากแหล่งข้อมูลที่จะแสดง นี่คือวัตถุชนิดและเราสามารถผูกชนิดใดก็ได้ที่มาจากประเภทวัตถุด้วยคุณสมบัตินี้ เนื่องจากเราจะใช้การรวม MVVM สำหรับกล่องคำสั่งผสมของเราในกรณีนี้นี่เป็นคุณสมบัติที่เราสามารถใช้เพื่อแจ้งเตือน VM ว่ามีการเลือกรายการแล้ว

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


1

ทุกการควบคุมที่ใช้ Collections เพื่อเก็บข้อมูลจะมีคุณสมบัติ SelectedValue, SelectedItem ตัวอย่างของตัวควบคุมเหล่านี้คือ ListBox, Dropdown, RadioButtonList, CheckBoxList

จะมีความเฉพาะเจาะจงมากขึ้นถ้าคุณต้องการดึงข้อความจากรายการที่เลือกคุณสามารถเขียน:

ListBox1.SelectedItem.Text;

ListBox1 ของคุณยังสามารถส่งคืนข้อความโดยใช้คุณสมบัติ SelectedValue หากค่าได้ตั้งไว้ก่อนหน้านี้ แต่ข้างต้นเป็นวิธีที่มีประสิทธิภาพมากขึ้นในการรับข้อความ

ตอนนี้ค่าเป็นสิ่งที่ผู้ใช้ไม่สามารถมองเห็นได้ แต่ส่วนใหญ่จะใช้เพื่อจัดเก็บในฐานข้อมูล เราไม่ใส่ข้อความของ ListBox1 แต่เราสามารถแทรกข้อความได้ แต่เราใช้เพื่อแทรกค่าของรายการที่เลือก เพื่อให้ได้คุณค่าเราสามารถใช้

ListBox1.SelectedValue

แหล่ง

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