WPF数据网格响应 - 20x50单元格

时间:2012-11-08 16:06:42

标签: c# wpf datagrid

我们正在努力解决wpf中数据网格的缓慢问题。无论我们使用哪个集合--List,BindingList,ObservableCollection,自定义ObservableCollection,它在响应集合更新(清除,添加)和在屏幕上渲染时仍然非常慢。

我们发现的最快解决方案不是更新集合,而是更新DataGrid绑定的集合中的exsting对象。在这种情况下,网格响应非常快,就像旧的winforms网格一样。

我们在网格中创建了65535行,这对我们所有的网格都足够了。在更新网格时,我们会更新所需的顶行数,并为其余行设置visibility = hidden。正如我所说,它的工作速度非常快。但是有两个问题我们无法解决:

  1. 滚动条,因为我们不会折叠行(它很慢) - 它始终设置为65535行。有没有办法将滚动或网格大小限制为实际可见行数?
  2. 另外,我注意到,在集合中添加新行,如果它们不需要立即渲染(它们将在可见区域之外)也非常快,所以我们可以将最小集限制为50行(最大可见行),然后根据需要添加/删除新行。但这并不能解决滚动问题。

    欢迎任何其他解决方案。 预见到启用虚拟化的建议 - 是的,我们正在使用虚拟化(对于默认启用的行和列)。

    更新: 我们正在尝试显示20列x 50行数据。如果我们使用Clear()然后使用Add()修改源集合,则渲染时间约为1秒,这对我们来说根本不可接受,因为UI被冻结了一秒钟。我试图将datagrid的大小调整为0 Height,然后在后台线程中逐步设置大小,它解冻UI,但忽略了丑陋,我还没有管理如何设置datagrid来填充父控件。似乎在代码中设置了高度之后,就没有办法了。 与最初的帖子一样,我们发现备用解决方案不会修改集合。只需将网格限制为65535行,不要添加或删除新项目。它工作得非常快,但现在我们在同步滚动和排序方面遇到了问题 我发现数据网格在WPF中非常令人沮丧。性能低于任何合理的限制。 我们要努力实现的是响应能力。加载数据时,它不应阻止UI超过几毫秒。

    XAML:没什么特别的

    <DataGrid x:Name="TheGrid" 
                              DockPanel.Dock="Top"
                              ItemsSource="{Binding Collection}"  
                              EnableColumnVirtualization="True"
                              EnableRowVirtualization="True"              
                              AutoGenerateColumns="False"
                              ColumnWidth="70"
                              RowHeight="20"
    
                              >
    
    
                        <DataGrid.Columns>
                            <DataGridTemplateColumn Header="Header 1" >
    
                                <DataGridTemplateColumn.CellEditingTemplate>
                                    <DataTemplate>
                                        <TextBox Text="{Binding Field1, Mode=TwoWay}" />
                                    </DataTemplate>
                                </DataGridTemplateColumn.CellEditingTemplate>
    
                                <DataGridTemplateColumn.CellTemplate>
                                    <DataTemplate>
                                        <TextBlock Text="{Binding Field1}" /></DataTemplate>
                                </DataGridTemplateColumn.CellTemplate>
    
                            </DataGridTemplateColumn >
    

    .....等20列

    此外,datagrid不在StackPanel内(这使得它非常慢)。

3 个答案:

答案 0 :(得分:1)

最后,我们发现如何将滚动限制为任意数量的行而不是太多。 我们创建了自己的绑定列表,它实现了ICollection,它在ScrollView中用于获取行数。我们更改了ICollection.Count以返回在调用Measure之前设置的可见行数,然后我们将其设置回实际计数。它工作得很好,它通过滚动解决了我们所有的问题。 所以,我们有一个网格,它绑定到具有静态行数的列表,我们设置visibility =可见到我们要显示的n个第一行,其余的可见性隐藏(不是Collapesed,因为Collapsing非常慢) ,我们将滚动限制为可见行。列表中的对象可以从不同的线程更新,我们不需要调用Dispatcher,因为WPF本身就是这样做的。

答案 1 :(得分:0)

我找到了可能对您有用的网页。

第一个是关于缓存datagrid中的值: http://msdn.microsoft.com/en-us/library/system.windows.uielement.cachemode(v=vs.100).aspx

关于为datagrid实现虚拟模式的第二个: http://msdn.microsoft.com/en-us/library/15a31akc.aspx

我希望它可以帮到你

更新: 你在使用滚动视图吗?因为如果你是它将加载所有行而不是仅可见。请尝试查看此问题的答案:How to lazy-evaluate a wpf:DataGrid, retrieving data only as needed

答案 2 :(得分:0)

我知道它可能不是正确的解决方案,因为它仍然需要相同的时间。但制作多线程将解决冻结问题。然后你可以让它在背景中填充网格中的数据并逐个添加它们,或者在完成时将它们全部添加。