使用DataGrid时,ScrollViewer的性能较慢

10
我有以下情况:
<ScrollViewer>
    <Grid>
         <!--many other controls-->
         <DataGrid />
    </Grid>
</ScrollViewer>

现在,当我将DataGrid绑定到大量数据(约10,000行)时,我的性能非常缓慢。实际上,我遇到了OutOfMemory异常(而且我有8 GB内存)!我在某处读到,这是因为ScrollViewer覆盖了DataGrid的虚拟化(或类似的东西),但是我不知道如何防止这种情况发生。如果我移除ScrollViewer,问题得到解决!数据在不到一秒钟内加载。

我想保留ScrollViewer(因为其他控件),并且获得良好的性能。这可能吗?如果不行,是否有任何其他解决方法或变通方法?

2个回答

8

针对这些问题的常见解决方法是在与DataGrid相同的行中添加一个不可见的“调整元素”,然后您可以将DataGrid.Height绑定到调整元素的ActualHeight。这样,您的DataGrid将始终消耗RowDefinition的高度。 示例:

<ScrollViewer>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Button Content="Some Control.." />
        <Rectangle Name="sizingElement"
                   Grid.Row="1"
                   Fill="Transparent"
                   Margin="1"/>
        <DataGrid Grid.Row="1"
                  Height="{Binding ElementName=sizingElement,
                                   Path=ActualHeight, FallbackValue=1}">
            <!--...-->
        </DataGrid>
        <Button Content="Some more controls etc.." Grid.Row="2"/>
    </Grid>
</ScrollViewer>

@Vale:我不明白,除非将DataGrid减少到0的高度,否则外部滚动查看器将不再起作用。为什么你想要这样的东西? - H.B.
@H.B.:这也可能取决于其他因素。如果你有三行,像是Auto、*、Auto,并将DataGrid放在中间行,设置MinHeight为100,同时在最后一行放置一个高度从10到1000不等的控件,外部的ScrollViewer会在需要时滚动控件,而DataGrid的ScrollViewer则会滚动DataGrid。 - Fredrik Hedblad
2
@Meleak:嗯,说得好。但我不禁想到一定有更好的方法来做这件事,我已经用实际大小绑定了各种各样的东西,但这似乎有点不合适... - H.B.
很棒的解决方法。这解决了一个类似的问题,让我感到疯狂。 - Jason Massey

4

外部的ScrollViewer实际上为DataGrid提供了足够的空间,使其高度变得很大,一次性显示所有行。只需通过显式设置高度来限制DataGrid即可。


1
实际上,那不是最好的解决方案。如果我现在调整窗口大小,DataGrid 将不会随之调整大小。 - Vale
@Vale:你应该只将ScrollViewer放置在其他控件的网格单元中。 - H.B.
为什么我要将ScrollViewer放在单元格内?我希望整个窗口都可以滚动,所以我将其放在网格周围。该网格是窗口的内容。 - Vale
实际上是这样的。我的整个团队都在努力寻找解决这个特定问题的方法,但到目前为止没有人能够做到。限制DataGrid的大小不是一个选项,它的宽度和高度没有设置,因此它会随着网格单元格的大小而调整大小,而网格单元格的大小设置为*。ScrollViewer是内容,但也没有大小,因此它始终适合窗口大小。我们需要这种行为方式用于许多项目... - Vale
@Vale:所以你想要整个数据网格都在外部滚动视图中滚动,但它应该虚拟化其项目吗?如果是这样,我不建议这样做,首先外部滚动视图不关心列标题,因此它们可以滚动出视图,其次实现这一点以实际虚拟化为非常困难,所以我根本不建议这样做。数据网格不适合由外部ScrollViewers滚动。 - H.B.
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接