Tôi có nên liên kết với ICollectionView hay ObservableCollection


83

Một người có nên liên kết DataGridvới

ICollectionView = CollectionViewSource.GetDefaultView(collection)

hoặc với

ObservableCollection<T> collection; ???

Cách thực hành tốt nhất cho MVVM là gì và tại sao?

Câu trả lời:


129

Bạn luôn ràng buộc với một ICollectionView, cho dù bạn có nói rõ ràng hay không.

Giả sử rằng chúng ta có

var collection = new ObservableCollection<string>();
var collectionView = CollectionViewSource.GetDefaultView(collection);

Trong trường hợp này, ràng buộc với collectionhoặc với collectionViewlà một và giống nhau: công cụ liên kết sẽ liên kết với chế độ xem bộ sưu tập mặc định (có giá trị tham chiếu bằng collectionView) nếu bạn yêu cầu nó liên kết với collection.

Điều này có nghĩa là câu trả lời cho câu hỏi của bạn là "hoàn toàn không có gì khác biệt".

Chỉ cần hoàn toàn rõ ràng: ngay cả khi bạn liên kết trực tiếp với bộ sưu tập, công cụ liên kết sẽ liên kết với chế độ xem mặc định. Việc sửa đổi các thuộc tính của dạng xem, chẳng hạn như tiêu chí sắp xếp sẽ ảnh hưởng đến liên kết dường như liên kết trực tiếp với bộ sưu tập, vì đằng sau các bìa đó là ràng buộc đối với chế độ xem mặc định.

Tuy nhiên, có một câu hỏi thú vị và liên quan khác: người ta có nên liên kết với chế độ xem bộ sưu tập mặc định (tức là, với chính bộ sưu tập, vì không có lý do gì để liên kết rõ ràng với chế độ xem mặc định) hay với một chế độ xem khác của cùng một bộ sưu tập?

Xem xét rằng mỗi chế độ xem có khái niệm riêng về mục hiện tại, tiêu chí sắp xếp, v.v., theo đó, nếu bạn định có nhiều liên kết với cùng một bộ sưu tập và các điều khiển liên kết cần phải có khái niệm riêng biệt về mục, bộ lọc và công ty hiện tại, thì những gì bạn muốn là liên kết rõ ràng với nhiều chế độ xem của cùng một tập hợp cơ bản.


1
Câu trả lời tuyệt vời. Sở thích của riêng tôi là liên kết với ObservableCollection vì nó là một phần của System.Collections và "cảm thấy" đại diện hơn cho điều gì đó mà tôi đang đại diện về Model trái ngược với View, nhưng MVVM đôi khi hơi khó theo cách này.
Berryl

Tạo câu trả lời. Tôi chỉ muốn chỉ ra rằng trong Silverlight, một CollectionView mặc định sẽ không được tạo cho các bộ sưu tập liên kết trừ khi bộ sưu tập liên kết đó triển khai ICollectionViewFactory.
jspaey

Điều này cũng / vẫn áp dụng cho các ứng dụng Toàn cầu chứ?
Robert MacLean

@RobertMacLean: Tôi không có bất kỳ kinh nghiệm phát triển WP nào nên rất tiếc là không có ý kiến.
Jon

Để tạo một dạng xem rõ ràng cho một tập hợp cơ bản trong xaml, hãy tạo một phần tử CollectionViewSource trong Tài nguyên. Có liên kết thuộc tính CollectionViewSource.Source với bộ sưu tập cơ bản. Sau đó, liên kết thuộc tính ItemsControl.ItemSource của bạn với CollectionViewSource mà bạn đã tạo trong tài nguyên thông qua StaticResource. Bằng cách này, thao tác sắp xếp / lọc / nhóm được áp dụng cho một chế độ xem sẽ không "làm ô nhiễm" các MụcControls khác đang liên kết với Chế độ xem bộ sưu tập mặc định.
Frank Liu

35

ObservableCollection<T>triển khai INotifyCollectionChangedvà sẽ thông báo cho UI khi các mục trong bộ sưu tập đã được thay đổi.

ICollectionViewsẽ cung cấp cho bạn khả năng lọc, sắp xếp hoặc nhóm tập hợp ngoài việc đề xuất INotifyCollectionChangedcác sự kiện nếu tập hợp bên dưới triển khai nó.

Một trong hai loại hoạt động tốt với MVVM miễn là bạn liên kết với nó. Sử dụng ICollectionViewkhi bạn cần sắp xếp, lọc hoặc nhóm. Sử dụng ObservableCollection<T>trực tiếp khi bạn không sử dụng.


Bài đăng khác này có vẻ mâu thuẫn với việc ICollectionView sẽ tự động được cập nhật dựa trên sự kiện thay đổi bộ sưu tập ... có sai không? stackoverflow.com/a/17906474/3195477
UuDdLrLrSs

@UuDdLrLrSs nếu các mục trong bộ sưu tập được sửa đổi, giao diện người dùng liên kết với các mục đó hoặc thuộc tính của các mục đó, sẽ cập nhật mà không cần gọi Làm mới trên bộ sưu tập. Bài đăng khác hỏi cụ thể về việc thay đổi thuộc tính của các mục trong bộ sưu tập và tự động kích hoạt làm mới ICollectionView để đảm bảo nó chỉ bao gồm các mục vẫn phù hợp với tiêu chí bộ lọc. Dựa trên câu trả lời trong bài đăng khác, bạn sẽ phải gọi phương thức Refresh () để cập nhật "danh sách" các mục trong bộ sưu tập.
Jimmie R. Houts

9

Chỉ để thêm vào những gì Jon đã nói. Sự khác biệt chính là bằng cách sử dụng CollectionViewSource.GetDefaultView(collection), bạn đang làm cho ViewModel của bạn phụ thuộc vào WPF. Nhiều người theo chủ nghĩa thuần túy MVVM không thích điều này và điều này sẽ chỉ để lại tùy chọn hợp lệ cho ObservableCollection.

Tùy chọn khác sẽ là sử dụng ICollectionViewvà sử dụng một lớp, triển khai nó, nhưng không phải là một phần của chính WPF.


1
Đó không phải là sự khác biệt chính. Lưu ý thẻ wpf. "[nếu] các điều khiển liên kết cần có khái niệm riêng biệt về mục, bộ lọc và công ty hiện tại, thì điều bạn muốn là liên kết rõ ràng với nhiều chế độ xem của cùng một bộ sưu tập cơ bản". Đó là sự khác biệt. Là một "người theo chủ nghĩa thuần túy", bất kể điều đó là gì, có nghĩa là bạn không thể lọc, v.v. Hãy xem câu trả lời của Jimmie Houts tập trung vào sự khác biệt thực tế trong ngôn ngữ rõ ràng hơn.
Dirk Bester

7

Tôi không nghĩ vì vậy nó phải làm bất cứ điều gì với MVVMchính nó. ICollectionViewcung cấp các tính năng bổ sung như phân nhóm soring, v.v. nếu bạn cần những thứ đó, IColectionViewnếu không, chỉ cần sử dụngObservableCollection


2

Bạn sẽ liên kết với chế độ xem nếu bạn muốn lưới của mình hiển thị các cài đặt được áp dụng cho chế độ xem, ví dụ như lọc, nếu không thì chế độ xem là thừa.

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.