Список с тысячами изображений в обертке

Я пытаюсь создать список, который может содержать более тысячи изображений в виде сетки. С точки зрения дизайна это было бы очень похоже на это:

https://stackru.com/images/8af82687d863dad02d4d3cd0bef946ba653133b3.jpg

Поскольку я не могу использовать оболочку, так как это может нарушить виртуализацию пользовательского интерфейса, а панель стека не может отображать изображения в такой сетке (?), Я пытаюсь решить эту проблему с помощью модифицированной версии https://virtualwrappanel.codeplex.com/

Мой XAML:

<ListBox x:Name="GameWheel" ItemsSource="{Binding GameData}" ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.VerticalScrollBarVisibility="Hidden">
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <c:VirtualizingWrapPanel IsItemsHost="True" />
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Image x:Name="GameImage" Source="{Binding Path=ImagePath}" Width="{Binding ElementName=GameWheel, Path=ActualWidth, Converter={StaticResource widthConverter}}" />
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

Хотя этот подход работает, он все еще довольно медленный и глючит, особенно при использовании привязки по ширине изображения. Есть ли лучший способ архивации того же результата? Без кастомной обертки желательно.

1 ответ

Проверьте мою реализацию VirtualizingWrapPanel. Также доступно (с большим количеством включенных) от NuGet.

Этот код изначально взят из этой статьи CodeProject, которая в основном работала и, по-видимому, там же, где вы начали. Попутно я исправил несколько ошибок и улучшил производительность, чтобы она также могла вам помочь.

Обновление: ключ будет связывать с VirtualizingWrapPanel.ItemWidth скорее, чем Image.Width, В обеих реализациях была ошибка VirtualizingWrapPanel это предотвратит изменение размера детей, если ItemHeight или же ItemWidth значения изменились. Я исправил эту ошибку в этом коммите (строка 358).

По общему признанию это исправление грубой силы, но я хотел проверить кое-что для Вас и должен выйти. Я проверил это с 10000 изображений, и это было очень быстро. Я поработаю над лучшим решением (т. Е. Буду помнить только тогда, когда мы знаем, что значение изменилось) и обновлю этот ответ, когда я это сделаю.

Обновление 2: Быстрое изменение, чтобы улучшить ребенка. Измерьте этот коммит.

//TODO: If either child Height or Width == PositiveInfinity and the other side == ChildSlotSize then we probably don't need to measure. Need to test this
if (!child.DesiredSize.Equals(ChildSlotSize))
{
    child.Measure(ChildSlotSize);
}

Все еще есть возможности для улучшения, но сейчас нет времени для надлежащего тестирования, и это работает.

Другие вопросы по тегам