Wzorce żądań wiersza DataGrid z wirtualizacją danych

Zaimplementowałem rozwiązanie do wirtualizacji danych z wykorzystaniem kilku pomysłówCodePlex i blogBea Stollnitz oraz artykuł Vincenta Da Ven Berhge (ten sam link). Potrzebowałem jednak innego podejścia, więc postanowiłem napisać własne rozwiązanie.

UżywamDataGrid wyświetlić około miliona wierszy za pomocą tego rozwiązania. Używam również wirtualizacji interfejsu użytkownika. Moje rozwiązanie jest wykonalne, ale w pewnych sytuacjach doświadczam dziwnych zachowań, w jaki sposóbDataGrid żąda danych ze swojego źródła.

O rozwiązaniu

W końcu napisałem listę, która wykonuje całą ciężką pracę. Jest to ogólna klasa o nazwieVirtualList<T>. ImplementujeICollectionViewFactory interfejs, więc mechanizm tworzenia widoku kolekcji może utworzyćVirtualListCollectionView<T> przykład, aby go owinąć. Ta klasa dziedziczy zListCollectionView. Nie postępowałem zgodnie z sugestiami, aby napisać własneICollectionView realizacja. Dziedziczenie wydaje się działać dobrze.

TheVirtualList<T> dzieli całe dane na strony. Otrzymuje całkowitą liczbę przedmiotów i za każdym razemDataGrid żąda wiersza za pomocą indeksu list, ładuje odpowiednią stronę lub zwraca ją z pamięci podręcznej. Strony są przetwarzane wewnątrz iDispatcherTimer usuwa nieużywane strony w czasie bezczynności.

Wzorce żądań danych

Pierwszą rzeczą, której się dowiedziałem, toVirtualList<T> powinien wdrożyćIList (nie generyczne). W przeciwnym razieItemsControl potraktuje to jakoIEnumerable i zapytaj / wylicz wszystkie wiersze. To logiczne, ponieważDataGrid nie jest bezpieczny typ, więc nie może używaćIList<T> berło.

Wiersz z indeksem 0 jest często zadawany przezDataGrid. Wydaje się, że jest on używany do wizualnego pomiaru przedmiotów (zgodnie ze stosem wywołań). Więc po prostu buforuję ten.

Mechanizm buforowania wewnątrzDataGrid używa przewidywalnego wzorca do wysyłania zapytań do wyświetlanych wierszy. Najpierw prosi o widoczne rzędy od góry do dołu (dwa razy dla każdego wiersza), następnie pyta o kilka rzędów (w zależności od wielkości widocznego obszaru) przed widocznym obszarem (w tym pierwszym widocznym wierszu) w zstępującym zamów tak, od dołu do góry. Następnie żąda takiej samej liczby wierszy po widocznych wierszach (w tym ostatnim widocznym wierszu) od góry do dołu.

Jeśli widoczne są indeksy rzędu 4,5,6. Żądanie danych wynosi: 4,4,5,5,6,6,4,3,2,1,6,7,8,9.

Jeśli mój rozmiar strony jest prawidłowo ustawiony, mogę obsłużyć wszystkie te żądania z bieżącej i wcześniej załadowanej strony.

JeśliCanSelectMultipleItems jestTrue a użytkownik wybiera wiele elementów za pomocą przycisku SHIFT lub przeciągania mysząDataGrid wylicza wszystkie wiersze od początku listy do końca zaznaczenia. To wyliczenie odbywa się za pośrednictwemIEnumerable interfejs bez względu na toIList jest zaimplementowany lub nie.

Jeśli wybrany wiersz nie jest widoczny, a bieżący widoczny obszar jest „daleko” od wybranego wiersza, czasami DataGrid zaczyna żądać wszystkich elementów, od wybranego wiersza do końca widocznego obszaru. Włączenie wszystkich rzędów między nimi, które nie są nawet widoczne. Nie mogłem zrozumieć dokładnego wzoru tego zachowania. Może moja realizacja jest tego powodem.

Moje pytania

Zastanawiam się, dlaczegoDataGrid wnioski o niewidoczne wiersze, ponieważ te wiersze będą ponownie wymagane, gdy staną się widoczne?

Dlaczego konieczne jest żądanie każdego rzędu dwa lub trzy razy?

Czy ktoś może mi powiedzieć, jak sprawić, by DataGrid nie był używanyIEnumerable, z wyjątkiem wyłączania wyboru wielu elementów?

questionAnswers(1)

yourAnswerToTheQuestion