列表框在一个wrappanel中有数千个图像

时间:2015-08-27 20:25:45

标签: c# wpf listbox ui-virtualization

我试图创建一个列表框,其中可能包含类似于设计的网格中的一千多个图像。在设计方面,它与此非常相似:

http://i.stack.imgur.com/7URQD.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>

虽然这种方法有效,但它仍然很慢且有问题,特别是在图像宽度上使用bind时。是否有更好的方法来存档相同的结果?没有自定义的包装通道。

1 个答案:

答案 0 :(得分:1)

查看我对VirtualizingWrapPanel的实施情况。也可从NuGet获得(包含更多内容)。

此代码最初来自此CodeProject文章,该文章主要起作用,并且与您开始时的位置相同。在此过程中,我修复了一些错误并提高了性能,因此它也可能对您有所帮助。

更新:密钥将绑定到VirtualizingWrapPanel.ItemWidth而不是Image.WidthVirtualizingWrapPanel的两个实现中都存在一个错误,如果ItemHeightItemWidth值发生更改,则会阻止孩子调整大小。我在这个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);
}

仍然有改进的余地,但现在没有时间进行适当的测试,这很有效。