WPF DataGrid 的平滑滚动

25

我正在使用 WPF 数据表格,我所做的唯一修改是:

    <toolkit:DataGridTextColumn.ElementStyle>
       <Style TargetType="TextBlock">
       <Setter Property="TextWrapping" Value="Wrap"/>
      </Style>
    </toolkit:DataGridTextColumn.ElementStyle>
我进行了这样的修改,所以如果单元格内容较长,则会拉伸行高度,不会隐藏任何文本。问题出在DataGrid的滚动行为上——当滚动时,它会跳过整行,如果行高大于一行,则根本无法正常工作——滚动条在滚动时会抖动等等。
有没有办法使WPF DataGrid平滑地滚动,而不是逐行滚动?
谢谢。
4个回答

34

我没有直接使用过DataGrid,但事实是,如果使用 ScrollViewer.CanContentScroll=False,它会替换默认的 ItemsPanelTemplate,该模板使用 VirtualizedStackPanel 布局,替换为普通的 StackPanel。它可以平滑地滚动,但即使它不可见,它也会渲染每个项目。

如果你正在处理复杂的可视化树或大型数据集,这绝对会影响性能。


4
这个回答更加精确,因为它警告了禁用ScrollViewer.CanContentScroll和VirtualizedStackPanel的危险。 - Jānis Gruzis

30

DataGrid有一个附加属性,ScrollViewer.CanContentScroll,用于管理此行为。要获得平滑的滚动效果,您需要将其设置为False


4
该属性位于ScrollViewer命名空间中:ScrollViewer.CanContentScroll="False" - cpalmer
2
尝试将2500行x20列的DataTable绑定到DataGrid,结果程序无响应,内存消耗超过1GB,在等待加载完成几秒钟后我停止了等待。 - Jānis Gruzis
@JānisGruzis 这是一个不同的问题。这是在谈论数据网格一次滚动一行而不是平稳地滚动。对于你所说的问题,听起来像是你在一个ScrollViewer或Panel中显示整个网格,并且你正在滚动它,因此DataGrid认为整个东西都在显示。你需要使用网格的内部滚动查看器。 - Bryan Anderson
1
太棒了!对于那些需要编程的人来说... dataGrid1.SetValue(ScrollViewer.CanContentScrollProperty, false); - Gabe Halsmer
5
我建议使用 VirtualizingPanel.ScrollUnit="Pixel",这不会禁用虚拟化。 - marbel82

25
使用此代码:
<DataGrid VirtualizingPanel.ScrollUnit="Pixel">

不要使用CanContentScroll="False"。它会禁用虚拟化,导致在有大量行时加载时间很长。虚拟化意味着它只会渲染显示的数据,而不是整个数据表格的所有数据。

但是当您的行数不太多,但每一行都很复杂(包含复杂的数据模板/控件、大量数据等)时,禁用虚拟化可能会有所帮助。


@Ralms它是一个附加属性。我从未尝试过,但是快速的谷歌搜索显示可以通过这种方式设置附加属性。 如果你的DataGrid被命名为 <DataGrid x:Name="MyDataGrid"...>,那么你可以通过以下方式设置附加属性 VirtualizingPanel.SetScrollUnit(MyDataGrid, ScrollUnit.Pixel); - Welcor
是的,这是使用XAML。在我的情况下,许多UI都是在.cs文件上使用代码生成的,我只是创建了生成器函数来一遍又一遍地添加相同的元素。 所以在这种情况下,我正在执行正常的“var myDG = new DataGrid()”,但我不知道如何访问那些附加属性。有什么想法吗? - Ralms
1
@Ralms 应该是相同的过程。只需使用 myDG 作为名称 VirtualizingPanel.SetScrollUnit(myDG, ScrollUnit.Pixel); - Welcor
1
非常感谢,运行得很好。我不知道“附加属性”的这种方式。 - Ralms
VirtualizingPanel.ScrollUnit="Pixel" 对于我来说在平滑滚动方面没有任何作用。 - Hrvoje Batrnek

-3
  <DataGrid Grid.Row="1"
              CanUserAddRows="False" 
              CanUserDeleteRows="False" 
              CanUserReorderColumns="False" 
              CanUserSortColumns="False" 
              SelectionUnit="FullRow" 
              HeadersVisibility="None"
              Name="grd" 
              GridLinesVisibility="None"
              ItemsSource="{Binding}"
              AutoGenerateColumns="False" 
              ScrollViewer.CanContentScroll="False">
</DataGrid>

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