2010-07-22 64 views
14

Tôi cần hiển thị nhiều hàng trong lưới được thêm ở tần số khá cao (tối đa 10 hàng trên giây trong một số trường hợp) Tôi đã chọn ListView vì tôi giả định là điều khiển lưới nhanh nhất trong WPF. (chắc chắn nhanh hơn nhiều so với GridView)WPF: cách hiệu quả nhất/nhanh nhất để thêm các mục vào một ListView là gì?

Sử dụng CPU trở nên khá cao sau khi vài trăm nghìn mục được thêm vào và chúng tiếp tục đi vào. Điều này khá đáng ngạc nhiên vì ListView chỉ hiển thị các hàng có thể nhìn thấy, vì vậy nó không quan trọng như thế nào nhiều được thêm vào tổng số.

Cách tiếp cận đầu tiên của tôi là ràng buộc nó với ObservableCollection nhưng sau một thời gian, việc sử dụng CPU tăng lên và toàn bộ Cửa sổ trở nên bồn chồn.

Hơn tôi đã cố gắng ràng buộc nó vào một danh sách thường xuyên, mà dường như nhanh hơn, tuy nhiên tôi cần phải gọi .Refresh() trong danh sách thường, mà sau một thời gian slams CPU là tốt.

Hơn tôi đã cố gắng subclassing ObservableCollection để chèn đoạn với hy vọng rằng việc sắp xếp chúng sẽ cải thiện hiệu suất/giảm khối lượng công việc cpu, nhưng cách tiếp cận này dường như yêu cầu gọi CollectionView.Refresh giống như gọi Reset() trên bộ sưu tập, và cũng không thành công khi có rất nhiều mục trong bộ sưu tập.

Xóa phần quan sát và gọi myListView.Items.Refresh() để đưa nó trở lại 0 mang lại mức sử dụng CPU trở lại điểm xuất phát.

Bắt đầu chạy hết ý tưởng ở đây .. Một lần nữa, mục tiêu của tôi ở đây là thêm/hiển thị nhiều mục và hiển thị lưới 8 cột, theo cách hiệu quả nhất .. ListView có vẻ tốt, chỉ cần có một số cách tôi tiếp tục có thể tinh chỉnh nó ..

CẬP NHẬT

sau khi hồ sơ, ObservableCollection 800k hàng trong lưới điện, các cpu nhất công việc chuyên sâu được thực hiện bởi:

  • (75%) System. Windows.Media.MediaContext.RenderMessa geHandler (object resizedCompositionTarget)
  • (20%) ObservableCollection.OnCollectionChanged (NotifyCoolectionChanged ..)

mặc dù tùy thuộc vào phiên những con số khác nhau rất nhiều ..

UPDATE 2 .. ok BindingList dường như là người chiến thắng rõ ràng ở đây.

đây là kết quả (trong ve) cạnh nhau với 1 triệu hàng từng (và thêm 10 mặt hàng mỗi giây):

ObservableCollection: http://i.imgur.com/7ZoSv.png

BindingList http://i.imgur.com/jm5qF.png

bạn có thể xem tổng thể giảm hoạt động CPU, và khoảng một nửa số bọ ve cần thiết để xử lý cây trong trường hợp Danh sách ràng buộc! Cám ơn Akash vì ý tưởng tuyệt vời này.

Trả lời

16

Thay vì sử dụng ObservableCollection, tôi sẽ đề xuất lớp BindingList, bạn có thể làm điều gì đó như thế này ..

BindingList<string> list = new BindingList<string>(); 

list.AllowEdit = true; 
list.AllowNew = true; 
list.AllowRemove = true; 

// set the list as items source 
itemCollection.ItemsSource = list; 

// add many items... 

// disable UI updation 
list.RaiseListChangedEvents = false; 

for each(string s in MyCollection){ 
    list.Add(s); 
} 

// after all.. update the UI with following 
list.RaiseListChangedEvents = true; 
list.ResetBindings(); // this forces update of entire list 

Bạn có thể bật/tắt chức năng cập nhật ngay cả trong lô, thay vì thêm tất cả mọi thứ tại một shot, BindingList đã được hoạt động tốt hơn sau đó ObservableCollection trong tất cả các giao diện người dùng của tôi, tôi tự hỏi tại sao ở khắp mọi nơi người ta nói thêm về ObservableCollection khi BindingList thực sự superseds ObservableCollection.

+0

Akash, cảm ơn vì điều này. Tôi sẽ sớm kiểm tra bộ sưu tập này. Một điều tôi tò mò, là nếu có một cách để làm hàng loạt chèn w/ra làm mới toàn bộ danh sách. Tôi tin rằng đó là một nguồn cho nhiều jitter và cpu làm việc, khi 800k mục được làm mới vv –

+0

Tôi không nghĩ rằng nó sẽ làm mới 800k mục, bởi vì các tấm ảo hóa sẽ chỉ làm mới các mặt hàng hạn chế nếu họ đang trên màn hình. Tuy nhiên, một cách khác là đặt mục của bạn với một số loại máy nhắn tin, trong ứng dụng của tôi, tôi chỉ tải 0-20 lần đầu tiên và cho phép người dùng điều hướng từng người một, họ cũng có thể lọc bằng cách sử dụng một số loại tìm kiếm –

+2

danh sách ràng buộc của bạn? với ObservableCollection, tôi đã sử dụng CollectionViewSource vì nó cung cấp một bộ lọc, bộ lọc đó thực hiện trên mỗi mục được thêm vào. Bộ lọc đó là những gì có khả năng sẽ thực thi trên tất cả các hàng sau khi làm mới. Vì vậy, tôi sẽ cần phải tìm một cách khác để thêm lọc. –

Các vấn đề liên quan