2012-03-05 18 views
11

Jakie są potencjalne problemy związane z operacjami pomocniczymi, takimi jak lub RemoveRange? Musiał być powód, dla którego Microsoft ich nie dostarczył, teraz gdy ObservableCollection jest tak często używany w WPF.Dlaczego ObservableCollection nie obsługuje masowych zmian?

Można wdrożyć własną kolekcję obsługującą operacje zbiorcze i narzędzia INotifyCollectionChanged. Co się stanie, jeśli zwiążę taką kontrolę z ItemControl?

Czy ktoś wie o ItemsControls, które nie obsługują masowych zmian?

+6

Istnieje klasa BulkObservableCollection w Microsoft.VisualStudio.Language. Intellisense.BulkObservableCollection http://msdn.microsoft.com/en-us/library/dd867973.aspx – tofutim

Odpowiedz

3

Nie sądzę, że są potencjalne wady lub problemy, po prostu ich tam nie ma. W rzeczywistości okazuje się, że większość typów w "System.Collections.Generic" nie zapewnia funkcji "AddRange".

Tymczasem wiele osób stworzyło własne wersje "ObservableCollection", aby zapewnić pożądaną funkcjonalność.INotifyCollectionChanged zawiera wystarczającą ilość informacji dla swoich opiekunów, aby zanotować, kiedy pewna liczba przedmiotów została dotknięta prawdopodobnie z tego powodu.

Last but not least, jeśli wiążą kolekcję, która ma te operacje typu „Zakres” okaże się, że będą one pracować z UI jak można oczekiwać

4

Istnieje wiele rozszerzeń do ObservableCollection, które można znaleźć w Internecie, które dodają pojęcie zakresu dodawania/usuwania lub pozwalają odroczyć aktualizacje i uruchomić je ręcznie. Na przykład zobaczyć ten przepełnieniem stosu pytanie:

ObservableCollection Doesn't support AddRange method, so I get notified for each item added, besides what about INotifyCollectionChanging?

Można również wdrożyć dodatek zbiorczego że odpala zdarzenie Reset, który spowoduje, że interfejs do ponownego renderowania wszystkich elementów w kolekcji:

http://peteohanlon.wordpress.com/2008/10/22/bulk-loading-in-observablecollection/

Umożliwia to wydajniejsze zarządzanie aktualizacjami interfejsu użytkownika. W jaki sposób ItemsControl obsługuje zdarzenie zmienione kolekcji, które wyszczególnia listę zmienionych elementów, zależy od samej struktury WPF. Zakładam, że inteligentnie to obsługuje!

Moja rada jest dla ciebie, jeśli wydajność jest dla ciebie ważna i masz kolekcje z wieloma aktualizowanymi przedmiotami i masz problemy z wydajnością, to podklasa ObservableCollection zarządza powiadomieniem o zmianie kolekcji w sposób najlepiej odpowiadający potrzebom twojej aplikacji.

+0

Szybkie spojrzenie na implementację połączonego pytania pokazuje nieefektywną implementację. Zasadniczo zdarzenie "CollectorChanged" jest wywoływane dla każdego dodanego elementu, a następnie ponownie, aby zresetować kolekcję! –

+1

@KentBoogaart hi Kent, masz na myśli odpowiedź SO? dla mnie wygląda dobrze. Metoda AddRange iteruje nad dodanymi elementami, a następnie uruchamia pojedyncze zdarzenie CollectionChanged, z typem zmiany "add" dostarczającym listę dodanych elementów. Formatowanie kodu nie jest jednak zbyt dobre ;-) – ColinE

+1

, ponieważ RangeObservableCollection rozszerza ObservableCollection, wywołanie Add on each item powoduje podniesienie CollectChangedEvent dla każdego dodanego elementu. Następnie cały ten wysiłek marnuje się, resetując kolekcję po dodaniu wszystkich elementów. –

2

NotifyCollectionChangedEventArgs zawiera informacje indeksu. Usunięcie elementów powoduje przetasowanie indeksów, podobnie jak wstawianie elementów. Dlatego też, choć nie jest to całkowicie niemożliwe, byłoby raczej trudne i prawdopodobnie nieefektywne zapewnienie możliwości pracy z zakresami.

+0

Jedyną informacją indeksu jest "indeks, w którym nastąpiła zmiana". Ta informacja jest łatwo dostępna dzięki operacjom dodawania i usuwania zakresów. –

+0

@ A.R .: nie, a co jeśli usuniemy pierwszy i ostatni element kolekcji? W argach zdarzenia jest tylko jeden indeks, ale potrzebne są dwa indeksy. –

+0

Istnieją dwa indeksy. Jest "NewStartingIndex" i "OldStartingIndex". W opisie tego ostatniego czytamy: "Pobiera indeks, w którym wystąpiło działanie" przenieś, usuń lub zamień ". Ponadto, jeśli nie usuniesz WSZYSTKICH elementów z kolekcji, opisywany scenariusz nie jest możliwy, ponieważ elementy w zakresie są ciągłe. –

1

Musi być jakiś powód, dlaczego Microsoft nie zapewniają im

nie zapewniają one każdej możliwej kawałek funkcjonalności, to (także) koszt w porównaniu z popytem rzeczy.

Można wdrożyć własną kolekcję, która obsługuje operacje zbiorcze i narzędzia INotifyCollectionChanged.

Tak. A kiedy to zrobisz, okaże się, że kolekcja będzie musiała dokonać wyboru, jak/kiedy propagować te zmiany. Nigdy nie próbowałem, ale wyobrażam sobie, że istnieją pewne kompromisy, z którymi View lub ViewModel mogą podejmować lepsze decyzje niż kolekcja wielokrotnego użytku.

Powiązane problemy