Sự khác biệt giữa ObservableCollection và BindingList


236

Tôi muốn biết sự khác biệt giữa ObservableCollectionBindingList bởi vì tôi đã sử dụng cả hai để thông báo cho bất kỳ thay đổi thêm / xóa nào trong Nguồn, nhưng tôi thực sự không biết khi nào nên thích cái này hơn cái kia.

Tại sao tôi lại chọn một trong những thứ sau đây?

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

hoặc là

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

Câu trả lời:


278

Một ObservableCollectioncó thể được cập nhật từ UI chính xác như bất kỳ bộ sưu tập. Sự khác biệt thực sự là khá đơn giản:

ObservableCollection<T>thực hiện INotifyCollectionChangedcung cấp thông báo khi bộ sưu tập được thay đổi (bạn đoán ^^) Nó cho phép công cụ liên kết cập nhật giao diện người dùng khi ObservableCollectioncập nhật.

Tuy nhiên, BindingList<T>thực hiện IBindingList.

IBindingListcung cấp thông báo về thay đổi bộ sưu tập, nhưng không chỉ vậy. Nó cung cấp một loạt các chức năng mà UI có thể sử dụng để cung cấp nhiều thứ hơn là chỉ cập nhật UI theo các thay đổi, như:

  • Sắp xếp
  • Đang tìm kiếm
  • Thêm thông qua nhà máy (chức năng thành viên AddNew).
  • Danh sách chỉ đọc (thuộc tính CanEdit)

Tất cả các chức năng này không có sẵn trong ObservableCollection<T>

Một sự khác biệt nữa là BindingListchuyển tiếp thông báo thay đổi mục khi mục thực hiện INotifyPropertyChanged. Nếu một mục đặt ra một PropertyChangedsự kiện, BindingListsẽ nhận được nó một tăng một ListChangedEventvới ListChangedType.ItemChangedOldIndex=NewIndex(nếu một mục đã được thay thế, OldIndex=-1). ObservableCollectionkhông chuyển tiếp thông báo mục.

Lưu ý rằng trong Silverlight, BindingListkhông có sẵn dưới dạng tùy chọn: Tuy nhiên, bạn có thể sử dụng ObservableCollections và ICollectionView(và IPagedCollectionViewnếu tôi nhớ rõ).


5
Một điều khác cần xem xét là hiệu suất, xem: themissingdocs.net/wordpress/?p=465
Jarek Mazur

Cảm ơn bạn, tôi đã không biết về việc triển khai BindingList thực tế. Tôi có xu hướng sử dụng ObservableCollection và ICollectionView
Eilistraee

5
Mặc dù thông tin trong câu trả lời này là chính xác, bất kỳ người dùng WPF nào cũng nên cẩn thận: BindingList không triển khai INotifyCollectionChanged và sẽ gây rò rỉ bộ nhớ nếu bị ràng buộc với thuộc tính ItemSource của điều khiển. ObservableCollection thực hiện giao diện và sẽ không gây ra bất kỳ rò rỉ nào như vậy.
Brandon Hood

1
Nếu BindingList thực hiện sắp xếp, thì tại sao bạn không thể sắp xếp lưới bị ràng buộc với BindingList?
Robert Harvey

BindingListlỗi thời không?
Shimmy Weitzhandler

27

Sự khác biệt thực tế là BindingList dành cho WinForms và ObservableCollection dành cho WPF.

Từ góc độ WPF, BindingList không được hỗ trợ đúng cách và bạn sẽ không bao giờ thực sự sử dụng nó trong dự án WPF trừ khi bạn thực sự phải làm.


1
Hấp dẫn. Là một Dev của Silverlight, tôi không biết điều đó. Cảm ơn. Và nếu bạn muốn sắp xếp và lọc, các triển khai ICollectionView là bạn của bạn ^^
Eilistraee

27
Tại sao nó "Không được hỗ trợ"? ViewManager (nội bộ) nằm trong hội đồng PresentationFramework và hỗ trợ nó. Ví dụ, ràng buộc nó với ItemControl và các thông báo thay đổi được tôn trọng (nghĩa là các mục được thêm và xóa). Nếu nó là WinForms cụ thể thì nó có nên được đặt tốt hơn trong không gian tên Forms không?
David Kiff

7
Đồng ý với David, nó nằm trong không gian tên System.Collections nên nó được WPF hỗ trợ đầy đủ. WPF chỉ là một cách bố trí UI khác nhau.
Justin

13
Đồng ý với David, tôi thường xuyên sử dụng BindingList trong WPF vì ObservableCollection sẽ không đưa ra các thông báo thay đổi thuộc tính từ các mục của nó.
mất trí nhớ

3
Để đưa ra một ví dụ cho "không hỗ trợ": Tôi vừa tìm thấy rò rỉ bộ nhớ trong ứng dụng WPF của mình do một số BindingLists không triển khai INotifyCollectionChanged
Breeze

4

Sự khác biệt quan trọng nhất như tính năng và thông báo thay đổi về các yếu tố có trong đã được đề cập bởi câu trả lời được chấp nhận nhưng có nhiều điều khác, cũng đáng được đề cập:

Hiệu suất

Khi AddNewđược gọi, BindingList<T>tìm kiếm mục đã thêm bằng cách IndexOftra cứu. Và nếu Tthực hiện INotifyPropertyChangedchỉ mục của một yếu tố thay đổi cũng được tìm kiếm bởi IndexOf(mặc dù không có tra cứu mới miễn là cùng một mục thay đổi liên tục). Nếu bạn lưu trữ hàng ngàn phần tử trong bộ sưu tập, thì ObservableCollection<T>(hoặc IBindingListtriển khai tùy chỉnh với chi phí tra cứu O (1)) có thể được ưa thích hơn.

Hoàn thành

  • Các IBindingListgiao diện là một khổng lồ (có thể không phải là thiết kế sạch) và cho phép thực hiện chính để thực hiện chỉ là một tập hợp con của các tính năng của nó. Ví dụ, các AllowNew, SupportsSortingSupportsSearchingthuộc tính nói cho dù AddNew, ApplySortFindcác phương pháp có thể được sử dụng, tương ứng. Nó thường làm mọi người ngạc nhiên rằng BindingList<T>bản thân nó không hỗ trợ sắp xếp. Trên thực tế, nó cung cấp một số phương thức ảo cho phép các lớp dẫn xuất thêm các tính năng còn thiếu. Các DataViewlớp học là một ví dụ cho một đầy đủ IBindingListthực hiện; tuy nhiên, nó không dành cho các bộ sưu tập đánh máy ở nơi đầu tiên. Và BindingSourcelớp trong WinForms là một ví dụ lai: nó hỗ trợ sắp xếp nếu nó kết thúc một IBindingListtriển khai khác , hỗ trợ sắp xếp.

  • ObservableCollection<T>đã thực hiện đầy đủ INotifyCollectionChangedgiao diện (chỉ có một sự kiện duy nhất). Nó cũng có các thành viên ảo nhưng ObservableCollection<T>thường có nguồn gốc vì lý do tương tự như Collection<T>lớp cơ sở của nó : để tùy chỉnh các mục thêm / xóa (ví dụ: trong bộ sưu tập mô hình dữ liệu) thay vì điều chỉnh các tính năng ràng buộc.

Sao chép so với gói

Cả hai ObservableCollection<T>BindingList<T>có một hàm tạo, chấp nhận một danh sách đã có sẵn. Mặc dù chúng cư xử khác nhau khi chúng được khởi tạo bởi một bộ sưu tập khác:

  • BindingList<T>hoạt động như một trình bao bọc có thể quan sát được cho danh sách được cung cấp và những thay đổi được thực hiện trên BindingList<T>cũng sẽ được phản ánh trên bộ sưu tập cơ bản.
  • ObservableCollection<T>mặt khác chuyển một thể hiện mới List<T>cho hàm tạo cơ sở Collection<T>và sao chép các phần tử của bộ sưu tập gốc vào danh sách mới này. Tất nhiên, nếu Tmột kiểu tham chiếu thay đổi trên các phần tử sẽ hiển thị từ bộ sưu tập gốc nhưng bản thân bộ sưu tập sẽ không được cập nhật.

1

Thêm một sự khác biệt lớn giữa ObservableCollectionBindingListcó ích, và có thể là một yếu tố quyết định giá thầu trong chủ đề:

BindingList Danh sách thay đổi xử lý:

Thay đổi danh sách BindingList

ObservableCollection Thay đổi bộ sưu tập:

Bộ sưu tập ObervableCollection đã thay đổi

Tóm tắt về vấn đề trên: Nếu một tài sản của một vật phẩm được thay đổi BindingList, ListChangedsự kiện sẽ cung cấp cho bạn thông tin chi tiết đầy đủ về tài sản (trong PropertyDescriptor) và ObservableCollectionsẽ không cung cấp cho bạn điều đó. Trong thực tế ObservableCollectionsẽ không tăng sự kiện thay đổi cho một tài sản thay đổi trong một mục.

Kết luận trên liên quan đến INotifyPropertyChangedviệc thực hiện trong các lớp mô hình. Theo mặc định, không có sự kiện nào thay đổi nếu một thuộc tính được thay đổi trong một mục.


Tôi nghĩ rằng điều này (PropertyDescriptor) có thể là một nguồn gây rò rỉ bộ nhớ
Abdulkarim Kanaan
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.