我试图创建一个列表框,其中可能包含类似于设计的网格中的一千多个图像。在设计方面,它与此非常相似:
由于我无法使用包装,因为这会破坏用户界面虚拟化,并且堆叠面板无法在这样的网格中列出图像(?),我尝试使用修改后的问题解决此问题版本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>
虽然这种方法有效,但它仍然很慢且有问题,特别是在图像宽度上使用bind时。是否有更好的方法来存档相同的结果?没有自定义的包装通道。
答案 0 :(得分:1)
查看我对VirtualizingWrapPanel的实施情况。也可从NuGet获得(包含更多内容)。
此代码最初来自此CodeProject文章,该文章主要起作用,并且与您开始时的位置相同。在此过程中,我修复了一些错误并提高了性能,因此它也可能对您有所帮助。
更新:密钥将绑定到VirtualizingWrapPanel.ItemWidth
而不是Image.Width
。 VirtualizingWrapPanel
的两个实现中都存在一个错误,如果ItemHeight
或ItemWidth
值发生更改,则会阻止孩子调整大小。我在这个commit(第358行)修复了这个错误。
不可否认,这是一次蛮力修复,但我想为你办理入住手续,并且必须前往。我用10000张图片测试了它,非常活泼。我将研究一个更好的解决方案(即:只有当我们知道值已经改变时才重新测量)并在我这样做时更新这个答案。
更新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);
}
仍然有改进的余地,但现在没有时间进行适当的测试,这很有效。