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>

虽然这种方法有效,但它仍然非常缓慢且有问题,尤其是在对图像宽度使用绑定时。有没有更好的方法来归档相同的结果?最好没有定制包装板。

4

1 回答 1

1

查看我的VirtualizingWrapPanel实现。也可从NuGet获得(包括更多)。

此代码最初来自此CodeProject文章,该文章大部分都有效,并且似乎与您开始的地方相同。在此过程中,我修复了几个错误并提高了性能,因此它也可能对您有所帮助。

更新:关键是绑定到VirtualizingWrapPanel.ItemWidth而不是Image.Width. 两个实现中都存在一个错误,如果or值发生更改VirtualizingWrapPanel,将阻止子级调整大小。我在这个提交中修复了这个错误(第 358 行)。ItemHeightItemWidth

诚然,这是一个蛮力修复,但我想为你办理登机手续,不得不出发。我用 10,000 张图像对其进行了测试,它非常活泼。我将制定一个更好的解决方案(即:仅在我们知道值已更改时重新测量)并在我这样做时更新此答案。

更新 2:快速更改以改进 child.Measure 与此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);
}

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

于 2015-08-27T22:59:29.667 回答