2012-10-14 26 views
7

Dưới đây là những gì tôi có - một ListBox với một ItemsSource thiết lập để một ObservableCollection<T> - nơi T là lớp tùy chỉnh của tôi đại diện cho một tập tin, chỉ chứa 2 DependencyProperties: Tên file và ThumbnailPath. - Hộp danh sách cũng có DataTemplate tùy chỉnh được xác định, để hiển thị độc đáo hình ảnh và tên tệp bên dưới.không đồng bộ thêm vào ObservableCollection (hoặc thay thế)

Mục đích của hộp danh sách là hiển thị tệp video trong thư mục hiện tại (được chọn trong TreeView), với hình thu nhỏ (được tạo không đồng bộ; không phải là một phần của vấn đề này).

Vì vậy, khi tôi thay đổi thư mục trong TreeView, ObservableCollection sẽ bị xóa và được điền lại, được tự động phản ánh trong các mục ListBox.

Đây là vấn đề: Giao diện người dùng không phản hồi và mất vài giây để cập nhật. Một lần nữa, hình thu nhỏ không có ý nghĩa ở đây (tôi đã cố gắng vô hiệu hóa chúng). Tôi nghĩ rằng những gì mất nhiều thời gian nhất là xây dựng 50-100 trường hợp của lớp tùy chỉnh của tôi, và đại diện trực quan của họ - nó phải khởi tạo một đối tượng hình ảnh cho mỗi một. Nhưng đó chỉ là phỏng đoán của tôi - bạn có thể vui lòng xác nhận hoặc loại trừ khả năng này không?

Tôi bắt đầu nghĩ ObservableCollection có thể không phải là cách để đi ở đây, vì từ những gì tôi đọc và một chút so với những gì tôi đã cố gắng, không có cách nào để thêm các mục đồng bộ, ít nhất nếu các mặt hàng này là DependencyObjects. Tôi đã thử tạo ra các cá thể lớp của tôi với một BackgroundWorker và thêm chúng vào bộ sưu tập trong xử lý sự kiện ProgressChanged, nhưng nó ném một ngoại lệ (một số vấn đề luồng vs dependencyobjects).

Có điều gì đó tôi bị thiếu không? Hoặc tôi sẽ được tốt hơn bằng cách đơn giản là bỏ ObservableCollection và viết một async cũ tốt cho vòng lặp để thêm các mục?

+1

loại ngoại lệ chính xác và thông điệp là gì? – Adam

+0

"Phải tạo DependencySource trên cùng một Thread với DependencyObject" –

+0

Còn về 'Binding, IsAsync = True' thì sao? –

Trả lời

12

ObservableCollection của bạn bị ràng buộc với giao diện người dùng do đó nó được tạo trên chuỗi giao diện người dùng nên mọi cập nhật thêm (xóa/thêm/xóa) phải nằm trên cùng một chuỗi giao diện người dùng. Nó không cho phép cập nhật từ một chuỗi khác.

Tuy nhiên, những gì bạn có thể làm là tạo insance của lớp học của bạn (hoặc tất cả tiêu thụ hoạt động trên sợi nền thời gian) và một khi bạn đã làm xong, thêm các đối tượng trong ObservableCollection sử dụng Dispatcher của thread UI của bạn như thế này -

App.Current.Dispatcher.BeginInvoke((Action)delegate() 
          { 
           observableCollection.Add(instanceOfYourClass); 
          }); 

Điều gì Dispatcher làm là đặt hoạt động trên chuỗi được liên kết của nó. Do đó, mục sẽ luôn được thêm vào chuỗi giao diện người dùng nhưng có thể được tạo trong chuỗi nền.

Dưới đây là số liên kết mà có thể giúp bạn có được đi - Updating from BW và khác một here

+0

Cảm ơn, tôi sẽ thử điều này, và tôi chắc chắn sẽ kiểm tra bài viết thú vị, tuy nhiên tôi đã thử một cái gì đó tương tự (không thể tìm thấy nó bây giờ) mà không có may mắn ... Tôi nghĩ nó có vấn đề với lớp học của tôi DependencyObject. Một cái gì đó như "bạn không thể tạo ra một dependencyobject trên một sợi và sử dụng nó trên khác". –

+0

Vâng, DP của bạn phải được tạo trên chính chuỗi giao diện người dùng.Trong trường hợp bạn muốn ràng buộc nó với giao diện người dùng của bạn, bạn phải sử dụng DP nhưng trong trường hợp không, tôi sẽ đề xuất cho các thuộc tính 'POCO' đơn giản triển khai giao diện' INPC'. –

+0

Tôi muốn ràng buộc nó ... Tôi cần hộp danh sách để hiển thị một danh sách các cá thể lớp FILE của tôi, với bảng dữ liệu tùy chỉnh của tôi được áp dụng. Tôi nghĩ tôi sẽ đi với INPC. –

5

Với .net 4.5 bạn có thể sử dụng EnableCollectionSynchronization

object lockObj = new object(); 
     BindingOperations.EnableCollectionSynchronization(yourObservableCollection, lockObj); 
Các vấn đề liên quan