ความแตกต่างระหว่าง ObservableCollection และ BindingList


236

ฉันต้องการทราบความแตกต่างระหว่างObservableCollectionและBindingListเนื่องจากฉันใช้ทั้งคู่เพื่อแจ้งให้ทราบถึงการเปลี่ยนแปลงเพิ่ม / ลบใด ๆ ในแหล่งที่มา

ทำไมฉันต้องเลือกข้อใดข้อหนึ่งต่อไปนี้

ObservableCollection<Employee> lstEmp = new ObservableCollection<Employee>();

หรือ

BindingList<Employee> lstEmp = new BindingList<Employee>();

คำตอบ:


278

ObservableCollectionสามารถอัปเดตจาก UI เหมือนกับคอลเลกชันใด ๆ ความแตกต่างที่แท้จริงค่อนข้างตรงไปตรงมา:

ObservableCollection<T>ใช้เครื่องมือINotifyCollectionChangedที่ให้การแจ้งเตือนเมื่อมีการเปลี่ยนแปลงคอลเลกชัน (คุณเดาได้ว่า ^^) จะช่วยให้เอ็นจินการเชื่อมโยงปรับปรุง UI เมื่อObservableCollectionมีการอัปเดต

อย่างไรก็ตามการดำเนินการBindingList<T>IBindingList

IBindingListให้การแจ้งเตือนเกี่ยวกับการเปลี่ยนแปลงการรวบรวม แต่ไม่เพียงแค่นั้น มันมีฟังก์ชั่นมากมายที่ UI สามารถใช้เพื่อมอบสิ่งต่าง ๆ ได้มากกว่าการอัปเดต UI ตามการเปลี่ยนแปลงเช่น:

  • การเรียงลำดับ
  • ค้นหา
  • เพิ่มจากโรงงาน (ฟังก์ชั่นสมาชิก AddNew)
  • รายการแบบอ่านอย่างเดียว (คุณสมบัติ CanEdit)

ฟังก์ชันทั้งหมดนี้ไม่สามารถใช้งานได้ ObservableCollection<T>

ความแตกต่างก็คือว่าแจ้งเตือนการเปลี่ยนแปลงรีเลย์รายการเมื่อรายการของใช้BindingList INotifyPropertyChangedหากรายการหนึ่งเกิดขึ้นPropertyChangedเหตุการณ์BindingListจะได้รับมันเพิ่มListChangedEventด้วยListChangedType.ItemChangedและOldIndex=NewIndex(หากรายการถูกแทนที่OldIndex=-1) ObservableCollectionไม่ถ่ายทอดการแจ้งเตือนรายการ

โปรดทราบว่าใน Silverlight BindingListไม่สามารถใช้เป็นตัวเลือก: คุณสามารถใช้ObservableCollections และICollectionView(และIPagedCollectionViewถ้าฉันจำได้ดี)


5
สิ่งที่ควรพิจารณาอีกประการหนึ่งคือประสิทธิภาพโปรดดูที่: themissingdocs.net/wordpress/?p=465
Jarek Mazur

ขอบคุณฉันไม่ได้ตระหนักถึงการใช้งาน BindingList ที่แท้จริง ฉันมักจะใช้ ObservableCollection และ ICollectionView
Eilistraee

5
ในขณะที่ข้อมูลในคำตอบนี้ถูกต้องผู้ใช้ WPF ควรระวัง: BindingList ไม่ได้ใช้ INotifyCollectionChanged และจะทำให้หน่วยความจำรั่วหากถูกผูกไว้กับคุณสมบัติแหล่งรายการของแหล่งควบคุม ObservableCollection ใช้อินเทอร์เฟซและจะไม่ทำให้เกิดการรั่วไหลใด ๆ
Brandon Hood

1
หาก BindingList ดำเนินการเรียงลำดับแล้วทำไมคุณไม่สามารถจัดเรียงตารางที่ผูกไว้กับ BindingList ได้?
Robert Harvey

เป็นBindingListล้าสมัย?
Shimmy Weitzhandler

27

ความแตกต่างที่ใช้ได้คือ BindingList สำหรับ WinForms และ ObservableCollection สำหรับ WPF

จากมุมมอง WPF BindingList ไม่ได้รับการสนับสนุนอย่างเหมาะสมและคุณจะไม่เคยใช้มันในโครงการ WPF เว้นแต่คุณจะต้องทำ


1
น่าสนใจ ในฐานะนักพัฒนา Silverlight ฉันไม่ทราบ ขอบคุณ และถ้าคุณต้องการเรียงลำดับและกรองข้อมูลการใช้งานของ ICollectionView นั้นเป็นเพื่อนของคุณ ^^
Eilistraee

27
ทำไม "ไม่รองรับ" ViewManager (ภายใน) อยู่ภายในชุดประกอบ PresentationFramework และที่สนับสนุน ผูกเข้ากับ ItemsControl ตัวอย่างเช่นและการแจ้งเตือนการเปลี่ยนแปลงได้รับการเคารพ (เช่นรายการจะถูกเพิ่มและลบ) หากเป็นเฉพาะ WinForms ควรวางไว้ในเนมสเปซแบบฟอร์มหรือไม่
David Kiff

7
เห็นด้วยกับเดวิดมันอยู่ใน System.Collections namespace ดังนั้นจึงควรได้รับการสนับสนุนอย่างเต็มที่จาก WPF WPF เป็นเพียงรูปแบบ UI ที่แตกต่างกัน
Justin

13
เห็นด้วยกับเดวิดฉันใช้ BindingList บ่อยครั้งใน WPF เพราะ ObservableCollection จะไม่ทำให้การแจ้งเตือนการเปลี่ยนแปลงคุณสมบัติจากรายการ
ความจำเสื่อม

3
เพื่อให้ตัวอย่างสำหรับ "not supportet": ฉันเพิ่งพบหน่วยความจำรั่วในแอปพลิเคชัน WPF ของฉันที่เกิดจาก BindingLists บางคนไม่ได้ใช้ INotifyCollectionChanged
Breeze

4

ความแตกต่างที่สำคัญที่สุดเช่นฟีเจอร์และการแจ้งเตือนการเปลี่ยนแปลงเกี่ยวกับองค์ประกอบที่มีอยู่ถูกกล่าวถึงแล้วโดยคำตอบที่ยอมรับ แต่มีมากกว่าซึ่งก็น่ากล่าวถึง:

ประสิทธิภาพ

เมื่อAddNewมีการเรียกBindingList<T>การค้นหารายการที่เพิ่มโดยการIndexOfค้นหา และถ้าTใช้INotifyPropertyChangedดัชนีขององค์ประกอบที่ถูกเปลี่ยนแปลงก็จะถูกค้นหาด้วยIndexOf(แม้ว่าจะไม่มีการค้นหาใหม่ตราบใดที่รายการเดียวกันมีการเปลี่ยนแปลงซ้ำ ๆ ) หากคุณเก็บองค์ประกอบหลายพันรายการไว้ในคอลเลกชันค่าใช้จ่ายการค้นหาObservableCollection<T>(หรือการปรับIBindingListใช้แบบกำหนดเองด้วย O (1)) อาจเป็นที่นิยมมากกว่า

ความสมบูรณ์

  • IBindingListอินเตอร์เฟซที่เป็นใหญ่หนึ่ง (อาจจะไม่ได้การออกแบบที่สะอาด) และช่วยให้ implementors ที่จะใช้เฉพาะชุดย่อยของคุณสมบัติต่างๆ ยกตัวอย่างเช่นAllowNew, SupportsSortingและSupportsSearchingคุณสมบัติบอกได้ว่าAddNew, ApplySortและFindวิธีการที่สามารถนำมาใช้ตามลำดับ บ่อยครั้งที่คนแปลกใจที่BindingList<T>ตัวเองไม่สนับสนุนการเรียงลำดับ จริงๆแล้วมันมีวิธีการเสมือนจริงบางอย่างเพื่อให้ชั้นเรียนที่ได้รับเพิ่มคุณสมบัติที่ขาดหายไป DataViewระดับเป็นตัวอย่างสำหรับเต็มรูปแบบIBindingListการดำเนินงาน; อย่างไรก็ตามไม่ได้มีไว้สำหรับคอลเลกชันที่พิมพ์ในตอนแรก และBindingSourceคลาสใน WinForms เป็นตัวอย่างไฮบริด: รองรับการเรียงลำดับถ้ามันตัดIBindingListการใช้งานอื่นซึ่งรองรับการเรียงลำดับ

  • ObservableCollection<T>เป็นการใช้งานINotifyCollectionChangedอินเทอร์เฟซที่สมบูรณ์แล้ว(ซึ่งมีเพียงเหตุการณ์เดียว) นอกจากนี้ยังมีสมาชิกเสมือน แต่ObservableCollection<T>โดยทั่วไปแล้วจะได้รับด้วยเหตุผลเดียวกับCollection<T>คลาสพื้นฐานของมัน: สำหรับการปรับแต่งรายการเพิ่ม / ลบ (เช่นในการเก็บแบบจำลองข้อมูล) แทนที่จะปรับคุณสมบัติการเชื่อมโยง

คัดลอกกับการตัด

ทั้งสองObservableCollection<T>และBindingList<T>มีนวกรรมิกซึ่งยอมรับรายการที่มีอยู่แล้ว แม้ว่าพวกเขาจะทำงานแตกต่างกันเมื่อพวกเขาถูกยกตัวอย่างโดยการสะสมอื่น:

  • BindingList<T>ทำหน้าที่เป็นwrapper ที่สังเกตได้สำหรับรายการที่ให้ไว้และการเปลี่ยนแปลงที่ดำเนินการในBindingList<T>จะสะท้อนให้เห็นถึงคอลเลกชันพื้นฐานเช่นกัน
  • ObservableCollection<T>ในทางกลับกันส่งList<T>อินสแตนซ์ใหม่ไปยังตัวCollection<T>สร้างฐานและคัดลอกองค์ประกอบของคอลเลกชันดั้งเดิมลงในรายการใหม่นี้ แน่นอนถ้าTเป็นการเปลี่ยนแปลงประเภทการอ้างอิงในองค์ประกอบจะสามารถมองเห็นได้จากคอลเลกชันดั้งเดิม แต่คอลเลกชันตัวเองจะไม่ได้รับการปรับปรุง

1

อีกหนึ่งความแตกต่างที่ยิ่งใหญ่ระหว่างObservableCollectionและBindingListที่มีประโยชน์และอาจเป็นปัจจัยในการตัดสินใจเสนอราคาในหัวข้อ:

BindingList รายการเปลี่ยนตัวจัดการ:

การเปลี่ยนแปลงรายการ BindingList

ObservableCollection การเปลี่ยนแปลงการสะสม:

เปลี่ยนคอลเลกชัน ObervableCollection แล้ว

บทสรุปของบน:ถ้าคุณสมบัติของรายการมีการเปลี่ยนแปลงในBindingListการListChangedจัดกิจกรรมที่จะให้รายละเอียดที่สมบูรณ์ของคุณสมบัติ (ใน PropertyDescriptor) และObservableCollectionจะไม่ให้คุณว่า ในความเป็นจริง ObservableCollectionจะไม่เพิ่มเหตุการณ์การเปลี่ยนแปลงสำหรับคุณสมบัติที่มีการเปลี่ยนแปลงในรายการ

ข้อสรุปข้างต้นเกี่ยวข้องกับINotifyPropertyChangedการนำไปใช้ในคลาสโมเดล โดยค่าเริ่มต้นไม่มีเหตุการณ์ที่เกิดขึ้นหากมีการเปลี่ยนแปลงสถานที่ให้บริการในรายการ


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