在 ScrollViewer 中使用 WPF DataGrid 虚拟化

use*_*286 5 wpf datagrid virtualizingstackpanel

我知道 DataGrid 支持虚拟化,因此它仅为可见行创建网格单元。但是,这似乎仅在 DataGrid 大小受到限制的情况下才有效。

在我的场景中,DataGrid 放置在滚动查看器内,如下所示

<ScrollViever>
    <StackPanel>

        <more elements .../>

        <DataGrid ... />

        <more elements .../>

    </StackPanel>
</ScrollViever>
Run Code Online (Sandbox Code Playgroud)

这似乎破坏了虚拟化。在 DataGrid 应显示大量项目的情况下,即使在外部 ScrollViewer 中向下滚动之前,视觉树也会变得非常大。

有什么方法可以防止 DataGrid 预先创建所有单元格,而是在 ScrollViewer 向下滚动时创建它们?

编辑:基本上,托管此内容的页面应该像一个网页,顶部有一些文本,底部有一个大表格和更多文本。整个页面应该滚动,而不是顶部/底部始终可见且仅滚动网格的停靠视图。该设置实现了这一点,但由于一切都是预先创建的而受到影响。

另一个编辑:有没有办法检测数据网格的特定行已滚动到视图中?典型的延迟加载文章使用数据网格的滚动查看器向网格添加更多项目,这在这里不起作用。

dev*_*hog 5

是的,你有点回答了你自己的问题。如果将 DataGrid 放置在 ScrollViewer 或 StackPanel 或任何不将修复约束传递给 DataGrid 的控件中,则会破坏 DataGrid 中的虚拟化。

您可以通过提供 DataGrid.Width 和 DataGrid.Height 固定值来解决此问题。

您需要了解虚拟化的这些固定值。虚拟化需要修复祖先。

以下是如何给 DataGrid 固定大小:

只需将高度/宽度绑定到 ScrollViewer 或 Grid 即可。

<Grid x:Name="grid" >
   <ScrollViever>
       <StackPanel>

           <more elements .../>

           <DataGrid Width={Binding ElementName=grid, Path=Width..} Height={Binding ElementName...} />

           <more elements .../>

       </StackPanel>
   </ScrollViever>
<Grid>
Run Code Online (Sandbox Code Playgroud)

就是这样:)