ObservableCollection ve BindingList arasındaki fark


236

Ben arasındaki farkı bilmek istiyorum ObservableCollectionve BindingListçünkü ben Kaynak her türlü ekleme / silme değişikliği için her ikisini de kullandım, ama aslında ne zaman diğeri tercih tercih bilmiyorum.

Neden aşağıdakilerden birini diğerine tercih edeyim?

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

veya

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

Yanıtlar:


278

Bir ObservableCollection, herhangi bir koleksiyon gibi UI'den güncellenebilir. Gerçek fark oldukça basittir:

ObservableCollection<T>INotifyCollectionChangedkoleksiyon değiştiğinde bildirim sağlayan uygular (tahmin ettiğiniz ^ ^) Güncellendiğinde ciltleme motorunun kullanıcı arayüzünü ObservableCollectiongüncellemesini sağlar.

Ancak BindingList<T>uygular IBindingList.

IBindingListkoleksiyon değişiklikleriyle ilgili bildirimde bulunur, sadece bu değil. Değişikliklere göre yalnızca UI güncellemelerinden çok daha fazla şey sağlamak için UI tarafından kullanılabilen bir dizi işlevsellik sağlar:

  • sınıflandırma
  • Aranıyor
  • Fabrikadan ekleme (AddNew üye fonksiyonu).
  • Salt okunur liste (CanEdit özelliği)

Tüm bu işlevler ObservableCollection<T>

Diğer bir fark, BindingListöğeleri uygulandığında öğe değişikliği bildirimlerini aktarmasıdır INotifyPropertyChanged. Bir öğe bir PropertyChangedetkinliği arttırırsa, etkinliğe BindingLista ListChangedEventile ListChangedType.ItemChangedve OldIndex=NewIndex(bir öğe değiştirildiyse OldIndex=-1) ile bir yükseltilir . ObservableCollectionöğe bildirimlerini aktarmaz.

Silverlight'ta BindingListseçenek olarak mevcut olmadığını unutmayın: Ancak ObservableCollections ve ICollectionView(ve IPagedCollectionViewiyi hatırlıyorsam) kullanabilirsiniz.


5
Dikkate alınması gereken başka bir şey performans, bkz: themissingdocs.net/wordpress/?p=465
Jarek Mazur

Teşekkürler, BindingList'in gerçek uygulamasının farkında değildim. ObservableCollection ve ICollectionView kullanma eğilimindeyim
Eilistraee

5
Bu yanıttaki bilgiler doğru olsa da, herhangi bir WPF kullanıcısı dikkat etmelidir: BindingList, INotifyCollectionChanged uygulamıyor ve bir denetimin ItemsSource özelliğine bağlıysa bellek sızıntısına neden oluyor. ObservableCollection arabirimi uygular ve bu tür sızıntılara neden olmaz.
Brandon Hood

1
BindingList sıralama uygularsa, neden bir BindingList öğesine bağlı bir ızgarayı sıralayamıyorsunuz?
Robert Harvey

BindingListeskimiş?
Shimmy Weitzhandler

27

Pratik fark, BindingList'in WinForms için ve ObservableCollection'ın WPF için olmasıdır.

WPF perspektifinden bakıldığında, BindingList düzgün bir şekilde desteklenmemektedir ve gerçekten gerekmedikçe hiçbir zaman bir WPF projesinde kullanmazsınız.


1
İlginç. Silverlight Geliştirici olarak bunu bilmiyordum. Teşekkürler. Ve sıralama ve filtreleme istiyorsanız, ICollectionView uygulamaları arkadaşınız ^^
Eilistraee

27
Neden "Desteklenmiyor"? ViewManager (dahili) PresentationFramework montajı içindedir ve onu destekler. Örneğin bir ItemsControl'e bağlayın ve değişiklik bildirimlerine uyun (yani, öğeler eklenir ve kaldırılır). WinForms'a özgü olsaydı, Formlar ad alanına daha iyi yerleştirilmemeli miydi?
David Kiff

7
David ile anlaştı, System.Collections ad alanında, bu yüzden WPF tarafından tamamen desteklenmelidir. WPF, UI düzeninin sadece farklı bir yoludur.
Justin

13
David ile de aynı fikirdeyim, BindingList'i WPF'de sık sık kullanıyorum çünkü ObservableCollection öğelerinden özellik değişikliği bildirimlerini başlatmıyor.
amnezi

3
"Destek değil" için bir örnek vermek için: WPF uygulamamda INotifyCollectionChanged
Breeze

4

İçerdiği öğelerle ilgili özellikler ve değişiklik bildirimleri gibi en önemli farklar, kabul edilen cevap tarafından zaten belirtilmiştir, ancak daha da fazlası var, ayrıca belirtmeye değer:

Verim

Arandığında AddNew, BindingList<T>eklenen öğeyi bir aramayla arar IndexOf. Ve Tuygularsa INotifyPropertyChanged, değiştirilen bir öğenin indeksi de aranır IndexOf(ancak aynı öğe tekrar tekrar değiştiği sürece yeni bir arama yoktur). Koleksiyonda binlerce öğe saklarsanız, ObservableCollection<T>(veya IBindingListO (1) arama maliyetiyle özel bir uygulama) daha fazla tercih edilebilir.

tamlık

  • IBindingListArayüz büyük bir (belki değil en temiz tasarımı) ve uygulamacılarıdır özellikleri yalnızca bir alt kümesini uygulamak için izin verir. Örneğin AllowNew, SupportsSortingve SupportsSearchingözellikleri olup olmadığını söylemek AddNew, ApplySortve Findyöntem, sırasıyla kullanılabilir. BindingList<T>Sıralamayı desteklemediği genellikle insanları şaşırtır . Aslında, türetilmiş sınıfların eksik özellikleri eklemesine izin veren bazı sanal yöntemler sağlar. DataViewSınıf tam bir örnektir IBindingListuygulanması; ancak, ilk etapta yazılı koleksiyonlar için değildir. Ve BindingSourceWinForms'daki sınıf karma bir örnektir: sıralamayı destekleyen başka bir IBindingListuygulamayı sararsa sıralamayı destekler.

  • ObservableCollection<T>zaten INotifyCollectionChangedarayüzün tam bir uygulamasıdır (yalnızca tek bir etkinliği vardır). Ayrıca sanal üyeleri de vardır, ancak ObservableCollection<T>genellikle temel Collection<T>sınıfıyla aynı nedenden dolayı türetilir : ciltleme özelliklerini ayarlamak yerine öğeleri ekleme / kaldırma (örneğin bir veri modeli koleksiyonunda) için.

Kopyalama ve sarma

Her ikisi de ObservableCollection<T>ve BindingList<T>zaten var olan bir listeyi kabul eden bir kurucu var. Başka bir koleksiyon tarafından başlatıldığında farklı davransalar da:

  • BindingList<T>sağlanan liste için gözlemlenebilir bir sargı görevi görür ve üzerinde yapılan değişiklikler BindingList<T>de altta yatan koleksiyona yansıtılır.
  • ObservableCollection<T>diğer yandan List<T>, temel kurucuya yeni bir örnek Collection<T>iletir ve orijinal koleksiyonun öğelerini bu yeni listeye kopyalar. Tabii ki, Tbir referans türü ise, öğelerdeki değişiklikler orijinal koleksiyondan görülebilir, ancak koleksiyonun kendisi güncellenmez.

1

One Arasındaki daha büyük farkObservableCollection ve BindingListkullanışlı geliyor ve bu konuda bir teklif karar faktörü olabilir:

BindingList Liste Değişikliği İşleyicisi:

BindingList List Değişikliği

ObservableCollection Koleksiyon değişikliği:

ObervableCollection Koleksiyonu Değişti

Yukarıdakiler Özeti: Bir öğenin özelliği değiştirilirse BindingList, ListChangedetkinlik size özelliklerin tüm ayrıntılarını verir (PropertyDescriptor'da) ve ObservableCollectionbunu size vermez. Aslında ObservableCollection, bir öğede değiştirilen bir mülk için değişiklik olayını artırmaz.

Yukarıdaki sonuç INotifyPropertyChangedmodel sınıflarında uygulanmakla ilgilidir. Varsayılan olarak hiçbiri, bir öğede özellik değiştirilirse değiştirilen olayı yükseltmez.


Bence bu (PropertyDescriptor) bir bellek sızıntısı kaynağı olabilir
Abdulkarim Kanaan
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.