2011-06-21 11 views
5

Dwukrotne pytanie tutaj, ale myślę, że te dwa tematy są wystarczająco powiązane, aby zagwarantować ich integrację.Jak przyspieszyć renderowanie ListBox i filtrowanie ListCollectionView?

W naszej aplikacji mamy ListBox, który jest wypełniony dużą liczbą elementów. Każdy z tych elementów jest wyświetlany z dość skomplikowanym szablonem przedmiotów. Jest to z pewnością dość skomplikowane i chociaż można by je nieco zmniejszyć, prawdopodobnie nie mógłbym wydobyć ogromnej ilości. Elementy w ListBox pochodzą z ListCollectionView, który jest zbudowany z ObservableCollection<> obiektów do wyświetlenia.

Mamy dwa problemy.

Pierwszym jest to, że kiedy ponownie skonfigurować filtry dla ListCollectionViewRefresh i zadzwonić na nim, jest bardzo wyczuwalny lock-up na kilka sekund w interfejsie użytkownika podczas jego rozebrany i ponownie, a ListBox ponownie wypełnia. Czas trwania tego blokowania wydaje się być związany z liczbą elementów zawartych w ListBox i jest najdłuższy, gdy obszar roboczy ListBox jest pełen elementów. Jesteśmy prawie pewni, że blokada jest spowodowana odtworzeniem szablonów przedmiotów. Próbowałem włączyć wirtualizację, ale nie miało to wpływu na zmniejszenie lub wyeliminowanie spowolnienia. Patrzę również na inne optymalizacje, takie jak sprawdzanie naszych wiązań i modyfikowanie układów. Czy istnieje sposób na uniknięcie tego konkretnego problemu, przyspieszenie lub przeniesienie go do innego wątku? (Wiem, że ostatnia z nich jest bardzo mało prawdopodobna, ponieważ renderowanie jest jednoniciowe, ale być może jest pewne obejście ...)

Druga odnosi się do filtrowania na ListCollectionView. Chociaż nie jest to obecnie problemem, uważamy, że istnieje możliwość, że filtrowanie stanie się problemem i spowoduje zauważalne blokowanie wątku interfejsu użytkownika. Pracuję nad zmniejszeniem kosztów filtrowania, ale zastanawiałem się, czy istnieje metoda przenoszenia wywołania funkcji Odśwież na ListCollectionView na inny wątek? Żadna z moich dotychczasowych prób nie odniosła sukcesu, pozornie dlatego, że ListCollectionView nie automatycznie steruje określonymi zdarzeniami we właściwym wątku.

Bardzo pomocne byłyby wskazówki i wyjaśnienia wszelkich znanych lub potencjalnych rozwiązań tych dwóch problemów.

+0

Mam ten sam problem z moim projektem wpf. Znalazłeś rozwiązanie ? –

+0

Minęło trochę czasu. Wydaje mi się, że pamiętamy, że agresywnie zoptymalizowaliśmy szablon i zrefactowaliśmy filtrowanie, aby przenieść większość do innego wątku. To spowodowało, że blokowanie było znacznie mniej zauważalne. Niestety od tamtej pory zmieniłem pracę, więc nie wiem, czy wykonano jakąś dalszą pracę. Możliwe, że przełączyli się na kontrolę typu "ListBox" innej firmy, która działa lepiej - zrobiliśmy to dla naszych sieci. –

Odpowiedz

1

2 wskazówki od here, pierwszy może pomóc do wirtualizacji z ListBox:

list wirtualizacji i poglądów za pomocą VirtualizingStackPanel jak ItemsPanel na listach. Tworzy widoczne elementy tylko w czasie ładowania. Wszystkie pozostałe elementy są leniwe, gdy stają się widoczne. Należy pamiętać, że grupowanie lub CanContentScroll="True" uniemożliwia wirtualizację!

Włącz recykling kontenerów. Wirtualizacja przynosi wiele ulepszeń wydajności, ale kontenery zostaną usunięte i ponownie utworzone, jest to ustawienie domyślne. Ale można uzyskać większą wydajność w kontenerach recyklingowych ustawiając VirtualizingStackPanel.VirtualizationMode="Recycling"

zrobiłem wirtualizacji mojej ogromnej listy obiektów według techniki opisanej here on codeproject, działa ładnie

+0

To interesujący artykuł. Może to być przydatne, gdy czytamy obiekty, które pojawiają się w ListBox; Przyjrzę się jego implementacji. Jeśli chodzi o VirtualizingStackPanel: Mam go skonfigurowany, ale niestety nie zajął się stoisko ListBox. W każdym razie dzięki. –

+0

Oryginalny plakat zawiera poprawne pytanie dotyczące ListCollectionView i już włączył wirtualizację. Występuje w tym samym problemie: pojawia się Odśwież, aby odtworzyć elementy. Już potwierdziłem, że wirtualizacja działa poprzez przewijanie, ale kiedy filtruję lub sortuję używając widoku, WPF odtworzył wszystkie elementy w ListView. –

2

kilka ciekawych pomysłów w this SO wątku o renderingu DataGrid i wiążące - możesz je również zastosować do scenariusza listbox ...

+0

Myślę, że to może być potencjalne rozwiązanie, jeśli dodawaliśmy lub usuwaliśmy elementy. Podczas stosowania Filtra wydaje się, że ListBox musi zostać ponownie wypełniony. Jeśli jest to nieuniknione, to tak samo towarzyszy temu przeciągnięcie, co jest dość irytujące. Objawem renderowania jednowątkowego WPF. Mamy nadzieję, że w przyszłości znajdzie się na to lekarstwo. Na razie będę musiał spróbować jeszcze bardziej zoptymalizować nasz DataTemplate. Twoje zdrowie. –

2

Nie sądzę, że możesz wirtualizować I filtrować jednocześnie. Tak więc, gdybym był w twoich butach, trzymałbym się listy wirtualizacyjnych list i logiki filtrowania w innym wątku.Pewnie, może będziesz musiał napisać kod, który został już wcześniej napisany, ale czy nie blokuje twojego GUI? Warto było.

Powiązane problemy