Шаблоны запросов строк DataGrid с виртуализацией данных

Я реализовал решение для виртуализации данных, используя некоторые идеи изCodePlex и блогBea Stollnitz и Винсент Да Вен Берхгебумага (та же ссылка). Однако мне нужен был другой подход, поэтому я решил написать собственное решение.

Я используюDataGrid для отображения около миллиона строк с этим решением. Я также использую виртуализацию пользовательского интерфейса. Мое решение выполнимо, но в некоторых ситуациях я наблюдаю странное поведениеDataGrid запрашивает данные из своего источника.

О решении

Я закончил тем, что написал список, который выполняет всю тяжелую работу. Это универсальный класс с именемVirtualList. Он реализуетICollectionViewFactory интерфейс, поэтому механизм создания представления коллекции может создатьVirtualListCollectionView экземпляр, чтобы обернуть его. Этот класс наследует отListCollectionView, Я не последовал советам, чтобы написать свойICollectionView реализация. Наследование, похоже, тоже работает нормально.

VirtualList разбивает все данные на страницы. Он получает общее количество предметов и каждый раз, когдаDataGrid запрашивает строку через индексатор списка, загружает соответствующую страницу или возвращает ее из кэша. Страницы переработаны внутри иDispatcherTimer удаляет неиспользуемые страницы в простое.

Шаблоны запроса данных

Первое, что я узнал, чтоVirtualList следует реализоватьIList (не универсальный). В противном случаеItemsControl будет рассматривать это какIEnumerable и запросить / перечислить все строки. Это логично, так какDataGrid не является безопасным типом, поэтому он не может использоватьIList интерфейс.

Строка с индексом 0 часто задаетсяDataGrid, Кажется, он используется для визуального измерения элемента (в соответствии со стеком вызовов). Итак, я просто кеширую это.

Механизм кеширования внутриDataGrid использует предсказуемый шаблон для запроса строк, которые он показывает. Сначала он запрашивает видимые строки сверху вниз (два раза для каждой строки), затем запрашивает пару строк (в зависимости от размера видимой области) перед видимой областью (включая первую видимую строку) в нисходящем порядке. порядок так, снизу вверх. После этого он запрашивает одинаковое количество строк после видимых строк (включая последнюю видимую строку) сверху вниз.

Если видимые индексы строки 4,5,6. Запрос данных будет: 4,4,5,5,6,6,4,3,2,1,6,7,8,9.

Если размер моей страницы установлен правильно, я могу обслуживать все эти запросы с текущей и ранее загруженной страницы.

ЕслиCanSelectMultipleItems являетсяTrue и пользователь выбирает несколько элементов с помощью кнопки SHIFT или перетаскивания мышью,DataGrid перечисляет все строки от начала списка до конца выделения. Это перечисление происходит черезIEnumerable интерфейс независимо от тогоIList реализовано или нет.

Если выбранная строка не видна и текущая видимая область имеет виддалеко» из выбранной строки иногда DataGrid начинает запрашивать все элементы, от выбранной строки до конца видимой области. Включая все строки между которыми даже не видны. Я не мог понять точную модель этого поведения. Может быть, моя реализация является причиной этого.

Мои вопросы

Мне интересно, почемуDataGrid запросы на невидимые строки, так как эти строки будут запрашиваться снова, когда станут видимыми?

Почему необходимо запрашивать каждую строку два или три раза?

Может кто-нибудь сказать мне, как заставить DataGrid не использоватьIEnumerableкроме выключения выбора нескольких элементов?

Ответы на вопрос(1)

Ваш ответ на вопрос