Perbedaan antara ObservableCollection dan BindingList

236

Saya ingin tahu perbedaan antara ObservableCollectiondan BindingListkarena saya telah menggunakan keduanya untuk memberi tahu jika ada perubahan tambah / hapus di Sumber, tapi saya sebenarnya tidak tahu kapan harus memilih yang satu daripada yang lain.

Mengapa saya memilih salah satu dari yang berikut ini daripada yang lain?

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

atau

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

Jawaban:

278

Sebuah ObservableCollectiondapat diperbarui dari UI persis seperti koleksi apa pun. Perbedaan yang sebenarnya agak langsung:

ObservableCollection<T>mengimplementasikan INotifyCollectionChangedyang memberikan notifikasi ketika koleksi diubah (Anda tebak ^^) Ini memungkinkan mesin pengikat untuk memperbarui UI saat ObservableCollectiondiperbarui.

Namun, BindingList<T>implementasinya IBindingList.

IBindingListmemberikan pemberitahuan tentang perubahan koleksi, tetapi tidak hanya itu. Ini menyediakan sejumlah fungsionalitas yang dapat digunakan oleh UI untuk menyediakan lebih banyak hal daripada hanya pembaruan UI menurut perubahan, seperti:

  • Penyortiran
  • Mencari
  • Tambah melalui pabrik (fungsi anggota AddNew).
  • Daftar hanya baca (properti CanEdit)

Semua fungsi ini tidak tersedia di ObservableCollection<T>

Perbedaan lainnya adalah BindingListrelay pemberitahuan perubahan item saat item diterapkan INotifyPropertyChanged. Jika suatu item memunculkan suatu PropertyChangedevent, maka BindingListakan menerimanya sebuah menimbulkan ListChangedEventdengan ListChangedType.ItemChangeddan OldIndex=NewIndex(jika suatu item diganti, OldIndex=-1). ObservableCollectiontidak menyampaikan pemberitahuan item.

Perhatikan bahwa di Silverlight, BindingListtidak tersedia sebagai opsi: Namun Anda dapat menggunakan ObservableCollections dan ICollectionView(dan IPagedCollectionViewjika saya ingat dengan baik).

Eilistraee
sumber
5
Hal lain yang perlu dipertimbangkan adalah kinerja, lihat: themissingdocs.net/wordpress/?p=465
Jarek Mazur
Terima kasih, saya tidak mengetahui implementasi BindingList yang sebenarnya. Saya cenderung menggunakan ObservableCollection dan ICollectionView
Eilistraee
5
Meskipun informasi dalam jawaban ini benar, setiap pengguna WPF harus berhati-hati: BindingList tidak mengimplementasikan INotifyCollectionChanged dan akan menyebabkan kebocoran memori jika terikat dengan properti ItemsSource properti. ObservableCollection mengimplementasikan antarmuka dan tidak akan menyebabkan kebocoran seperti itu.
Brandon Hood
1
Jika BindingList mengimplementasikan penyortiran, maka mengapa Anda tidak bisa mengurutkan kisi yang terikat ke BindingList?
Robert Harvey
Apakah BindingListsudah usang?
Shimmy Weitzhandler
27

Perbedaan praktisnya adalah bahwa BindingList adalah untuk WinForms, dan ObservableCollection adalah untuk WPF.

Dari perspektif WPF, BindingList tidak didukung dengan benar, dan Anda tidak akan pernah benar-benar menggunakannya dalam proyek WPF kecuali Anda benar-benar harus melakukannya.

Dean Chalk
sumber
1
Menarik. Sebagai Dev Silverlight, saya tidak tahu itu. Terima kasih. Dan jika Anda ingin menyortir dan memfilter, implementasi ICollectionView adalah teman Anda ^^
Eilistraee
27
Mengapa "Tidak didukung"? ViewManager (internal) ada di dalam unit PresentationFramework dan yang mendukungnya. Ikatkan ke ItemsControl misalnya dan notifikasi perubahan dihormati (yaitu item ditambahkan dan dihapus). Jika itu adalah WinForms spesifik, bukankah sebaiknya ditempatkan di namespace Formulir?
David Kiff
7
Setuju dengan David, ada di System.Collections namespace sehingga harus didukung sepenuhnya oleh WPF. WPF hanyalah cara tata letak UI yang berbeda.
Justin
13
Setuju dengan David juga, saya sering menggunakan BindingList di WPF karena ObservableCollection tidak akan memunculkan pemberitahuan perubahan properti dari item-itemnya.
amnesia
3
Sebagai contoh untuk "not supportet": Saya baru saja menemukan kebocoran memori di aplikasi WPF saya yang disebabkan oleh beberapa BindingLists yang tidak mengimplementasikan INotifyCollectionChanged
Breeze
4

Perbedaan paling penting seperti fitur dan pemberitahuan perubahan tentang elemen yang terkandung sudah disebutkan oleh jawaban yang diterima tetapi ada lebih banyak, yang juga layak disebutkan:

Performa

Ketika AddNewdipanggil, BindingList<T>mencari item yang ditambahkan dengan IndexOfpencarian. Dan jika Tmengimplementasikan INotifyPropertyChangedindeks elemen yang diubah juga dicari oleh IndexOf(meskipun tidak ada pencarian baru selama item yang sama berubah berulang kali). Jika Anda menyimpan ribuan elemen dalam koleksi, maka ObservableCollection<T>(atau IBindingListimplementasi kustom dengan O (1) biaya pencarian) bisa lebih disukai.

Kelengkapan

  • The IBindingListantarmuka adalah satu besar (mungkin bukan desain terbersih) dan memungkinkan pelaksana untuk melaksanakan hanya sebagian dari fitur-fiturnya. Sebagai contoh, AllowNew, SupportsSortingdan SupportsSearchingsifat tahu apakah AddNew, ApplySortdan Findmetode dapat digunakan, masing-masing. Ini sering mengejutkan orang-orang yang BindingList<T>tidak mendukung penyortiran. Sebenarnya ia menyediakan beberapa metode virtual membiarkan kelas turunan menambahkan fitur yang hilang. The DataViewkelas adalah contoh untuk penuh IBindingListimplementasi; Namun, itu bukan untuk koleksi yang diketik di tempat pertama. Dan BindingSourcekelas di WinForms adalah contoh hibrid: ia mendukung pengurutan jika membungkus IBindingListimplementasi lain , yang mendukung pengurutan.

  • ObservableCollection<T>sudah merupakan implementasi INotifyCollectionChangedantarmuka yang lengkap (yang hanya memiliki satu acara). Ini juga memiliki anggota virtual tetapi ObservableCollection<T>biasanya diturunkan untuk alasan yang sama dengan Collection<T>kelas dasarnya : untuk menyesuaikan menambahkan / menghapus item (misalnya dalam koleksi model data) daripada menyesuaikan fitur yang mengikat.

Salin vs. pembungkus

Keduanya ObservableCollection<T>dan BindingList<T>memiliki konstruktor, yang menerima daftar yang sudah ada. Meskipun mereka berperilaku berbeda ketika mereka dipakai oleh koleksi lain:

  • BindingList<T>bertindak sebagai pembungkus yang dapat diamati untuk daftar yang disediakan, dan perubahan yang dilakukan pada BindingList<T>akan tercermin pada koleksi yang mendasarinya juga.
  • ObservableCollection<T>di sisi lain meneruskan List<T>contoh baru ke Collection<T>konstruktor dasar dan menyalin elemen koleksi asli ke daftar baru ini. Tentu saja, jika Tperubahan tipe referensi pada elemen akan terlihat dari koleksi asli tetapi koleksi itu sendiri tidak akan diperbarui.
György Kőszeg
sumber
1

Satu lagi Perbedaan besar antara ObservableCollectiondan BindingListyang berguna, dan dapat menjadi faktor keputusan tawaran pada topik:

BindingList Daftar Handler Perubahan:

Perubahan Daftar BindingList

ObservableCollection Perubahan koleksi:

Koleksi ObervableCollection Berubah

Penjelasan Ringkas Di Atas: Jika properti item diubah BindingList, ListChangedacara akan memberi Anda detail lengkap properti (di PropertyDescriptor) dan ObservableCollectiontidak akan memberi Anda itu. Bahkan ObservableCollectiontidak akan memunculkan acara perubahan untuk properti yang diubah dalam suatu item.

Kesimpulan di atas dalam hal INotifyPropertyChangeddiimplementasikan dalam kelas model. Secara default tidak ada yang memunculkan acara yang diubah jika properti diubah dalam suatu item.

Kylo Ren
sumber
Saya pikir ini (PropertyDescriptor) mungkin menjadi sumber kebocoran memori
Abdulkarim Kanaan