2015-08-27 2 views
1

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

http://i.stack.imgur.com/7URQD.jpg

Поскольку я не могу использовать WrapPanel как сломается виртуализации UI и StackPanel не может перечислить изображения в такой сетке (?) Я пытаюсь решить эту проблему, используя модифицированную версию 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> 

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

+0

Все ли предметы будут одинаковыми Ширина (и высота)? – Kcvin

+0

Я установил одну и ту же ширину на всех, но некоторые могут иметь разную высоту .... (у меня нет контроля над самими изображениями). Однако на данный момент я ограничиваю ширину, поэтому я всегда получаю 5 изображений в строке. – NeoID

ответ

1

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

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

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

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

Обновление 2: Быстрое изменение для улучшения положения ребенка. См. Это commit.

//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); 
} 

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

+0

Спасибо. Я также основывал свою версию на этом сообщении codeproject. Однако добавление ширины (привязка ее к размеру экрана), к сожалению, добавляет 5-10 секунд до загрузки страницы WPF, содержащей этот элемент управления. Настройки фиксированной ширины быстрее, но, к сожалению, не масштабируются с размером экрана. – NeoID

+0

@NeoID может попытаться установить привязку свойства 'ItemWidth'' VirtualizationWrapPanel' и установить 'Image' для заполнения доступного пространства? –

+0

Пробовал это также. Изменено 'VirtualizationWrapPanel' на' ', но затем все изображения исчезают. Работает фиксированная ширина. Я предполагаю, что что-то смешное идет по ширине привязки, просто не уверен, что, как он работает во всем остальном в моем коде. Он просто делит ширину на 5. – NeoID

Смежные вопросы